【问题标题】:SQL query to order by sum of sumsSQL查询按总和排序
【发布时间】:2021-03-30 07:02:46
【问题描述】:

提前感谢您的帮助。

解释我的问题最简单的方法可能是用一个例子,所以我建立了一个沙盒数据库,有两个表和以下内容:

类别

 supercategory | category
---------------+----------
 fruit         | apple
 fruit         | orange
 fruit         | banana
 vegetable     | carrot
 vegetable     | onion
 vegetable     | celery
 grain         | rice
 grain         | wheat
 grain         | barley

篮子

 category | amount
----------+--------
 apple    |      2
 carrot   |      4
 wheat    |      1
 orange   |      5
 celery   |      4
 orange   |      3
 barley   |      2
 barley   |      5
 apple    |      1
 carrot   |      2
 rice     |      5
 wheat    |      3
 onion    |      2

我要做的是查询每个类别的总和,如下所示:

SELECT 
    categories.superCategory, baskets.category, 
    SUM(baskets.amount::numeric) AS categorySum
FROM
    baskets 
LEFT OUTER JOIN 
    categories ON categories.category = baskets.category
GROUP BY 
    categories.superCategory, baskets.category
ORDER BY 
    superCategory;

返回:

 category | supercategory | categorysum
----------+---------------+-------------
 apple    | fruit         |           3
 orange   | fruit         |           8
 barley   | grain         |           7
 rice     | grain         |           5
 wheat    | grain         |           4
 carrot   | vegetable     |           6
 celery   | vegetable     |           4
 onion    | vegetable     |           2

结果表正是我想要的,除了排序。我想按总和对每个超类别进行排序,然后在每个超类别中按总和对每个类别进行排序。所以我想要这张桌子的顺序是:


barley | grain     | 7      <---- The total for the "grain" supercategory is 16, so put it first
rice   | grain     | 5
wheat  | grain     | 4
carrot | vegetable | 6      <---- The total for vegetables is 12
celery | vegetable | 4
onion  | vegetable | 2
orange | fruit     | 8      <---- The total for fruits is 11
apple  | fruit     | 3

我对 SQL 的经验不足,不知道如何最好地完成此任务。我尝试了一些嵌套的 SELECT 函数,但没有弄清楚如何让它正常工作,或者这是否是最好的方法。

【问题讨论】:

    标签: sql postgresql sql-order-by aggregate-functions window-functions


    【解决方案1】:

    您可以使用ORDER BY 子句中的窗口函数SUM() 来做到这一点:

    SELECT b.category, 
           c.superCategory, 
           SUM(b.amount::numeric) AS categorySum
    FROM baskets b LEFT OUTER JOIN categories c
    ON c.category = b.category
    GROUP BY c.superCategory, b.category
    ORDER BY SUM(SUM(b.amount::numeric)) OVER (PARTITION BY c.superCategory) DESC, 
             categorySum DESC;
    

    请参阅demo
    结果:

    > category | supercategory | categorysum
    > :------- | :------------ | ----------:
    > barley   | grain         |           7
    > rice     | grain         |           5
    > wheat    | grain         |           4
    > carrot   | vegetable     |           6
    > celery   | vegetable     |           4
    > onion    | vegetable     |           2
    > orange   | fruit         |           8
    > apple    | fruit         |           3
    

    【讨论】:

      【解决方案2】:

      你在找这个吗:

      select superCategory, category , categorySum from (
      SELECT 
          categories.superCategory, baskets.category, 
          SUM(baskets.amount) over ( partition by categories.superCategory,baskets.category) AS categorySum
      FROM
          baskets 
      LEFT OUTER JOIN 
          categories ON categories.category = baskets.category
      ) X
      group by superCategory, category , categorySum
      ORDER BY SUM(categorySum) over ( partition by superCategory) DESC,categorySum desc
      

      【讨论】:

      • 。 .子查询不是必需的。
      【解决方案3】:

      试试这个并使用JOINsubquery

      SELECT T.category
           , T.superCategory
           , T.Sums AS categorySum
        FROM
             (
              SELECT categories.superCategory
                   , baskets.category
                   , SUM(baskets.amount) AS Sums
               FROM baskets
               JOIN categories ON categories.category = baskets.category
              GROUP BY categories.superCategory, baskets.category
            )T
       JOIN (
             SELECT categories.superCategory
                  , SUM(baskets.amount) AS Sums
               FROM baskets
               JOIN categories ON categories.category = baskets.category
              GROUP BY categories.superCategory
            )TA ON T.superCategory = TA.superCategory
      ORDER BY TA.Sums DESC, T.Sums DESC
      

      查看这个sqlfiddle的结果

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2012-03-14
        • 1970-01-01
        • 2012-12-16
        • 1970-01-01
        • 2021-08-13
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多