Oracle SQL 堆叠帕累托图查询

Oracle SQL Query for Stacked Pareto Chart

我有一个 Oracle Table,其中包含类似于以下基本示例的数据:

+--------+----------+
| SERIES | CATEGORY |
+--------+----------+
| green  | apple    |
| green  | pear     |
| green  | pear     |
| yellow | apple    |
| yellow | apple    |
| yellow | pear     |
| yellow | pear     |
| yellow | pear     |
| yellow | banana   |
| yellow | banana   |
| yellow | banana   |
| red    | apple    |
+--------+----------+

我想生成一个类似帕累托图的数据,它应该看起来像堆叠帕累托图,

要创建此图,我想 运行 一个 SQL 查询并获得以下输出:

+----------+--------+-------+
| CATEGORY | SERIES | COUNT |
+----------+--------+-------+
| pear     | green  |     2 |
| pear     | yellow |     3 |
| apple    | green  |     1 |
| apple    | yellow |     2 |
| apple    | red    |     1 |
| banana   | yellow |     3 |
+----------+--------+-------+

实际 table 有数百万个条目,目前查询数据库需要花费大量时间,因为我当前使用的程序效率不高:

按每个类别中的条目数量对类别进行排序:

SELECT CATEGORY, COUNT(CATEGORY) FROM FRUIT GROUP BY CATEGORY ORDER BY COUNT(CATEGORY);

然后对于每个类别,我按系列顺序列出相关系列:

SELECT SERIES, COUNT(SERIES) FROM FRUIT WHERE CATEGORY = [current category] GROUP BY SERIES ORDER BY SERIES;

查询数据库(最好是单个 SQL 语句)以获得所需输出的最有效方法是什么?

您可以通过对 CATEGORYSERIES 进行分组来获得所需的结果:

SELECT 
    CATEGORY, SERIES, COUNT(*) 
FROM FRUIT 
GROUP BY CATEGORY, SERIES 
ORDER BY COUNT(*);

更新:

先按总 CATEGORY 排序,然后按绿色、黄色、红色排序,就像您预期的输出:

SELECT t1.*
FROM (
    SELECT 
        CATEGORY, SERIES, COUNT(*) AS CNT
    FROM FRUIT 
    GROUP BY CATEGORY, SERIES 
) t1
INNER JOIN (
    SELECT
        CATEGORY, COUNT(*) AS CNT
    FROM FRUIT
    GROUP BY CATEGORY
) t2
    ON t1.CATEGORY = t2.CATEGORY
ORDER BY 
    t2.CNT DESC,
    CASE t1.SERIES
        WHEN 'green' THEN 1
        WHEN 'yellow' THEN 2
        WHEN 'red' THEN 3
    END

一些更短的版本:

select category, series, CntS 
from (
  select  distinct count(category) over (partition by category) cntC,
   count(series)  over (partition by category, series ) cntS,
   category, series 
from fruit   ) Tab
order by CntC desc, cntS desc;