如何获得MAX(值的总和)以找到总数最大的类别? PostgreSQL

时间:2019-05-24 11:09:34

标签: postgresql

我有两个桌子。一个是交易,另一个是门票。在门票中,我有门票编号,类别名称(剧院,电影院,音乐会),门票价格。在交易中,我也有Ticket_Number。我想做的是为每个类别获取总金额,然后使用该数据选择货币最多的类别。

我已经设法获得每个类别的总和,但是我被困在这里

SELECT category, SUM (Tickets.Price) AS Price  
FROM Tickets,Transactions  
WHERE Tickets.ticket_num=Transactions.ticket_num  
GROUP BY Category  
ORDER BY Price DESC;

我知道我可以添加LIMIT 1,但我知道这是不正确的,因为2个或多个值可以相同

3 个答案:

答案 0 :(得分:1)

使用ROW_NUMBER根据价格的总和生成一个序列。然后,仅将匹配的聚合行限制为最高总价。

WITH cte AS (
    SELECT category, SUM(t1.Price) AS Price,
        ROW_NUMBER() OVER (ORDER BY SUM(t1.Price) DESC) rn  
    FROM Tickets t1
    INNER JOIN Transactions t2
        ON t1.ticket_num = t2.ticket_num  
    GROUP BY Category
)

SELECT category, Price
FROM cte
WHERE rn = 1
ORDER BY Price DESC;

请注意,如果您想捕获所有以最高价格并列的类别,则在出现并列的情况下,请使用ROW_NUMBER替换上方CTE中的RANK,其他所有内容保持不变。

答案 1 :(得分:1)

您正在寻找的是一个窗口函数DENSE_RANK(),它将正确处理领带。

RANK()也适用于您的情况,但是如果您想扩展它以在TOP N个有平局的地方(其中N > 1),那么密集的等级是可行的。

SELECT Category, Price
FROM (
  SELECT 
    Category, 
    SUM(ti.Price) AS Price, 
    DENSE_RANK() OVER (ORDER BY SUM(ti.Price) DESC) AS rnk
  FROM Tickets ti
  INNER JOIN Transactions tr ON
    ti.ticket_num = tr.ticket_num  
  GROUP BY Category
  ) t
WHERE rnk = 1

我还替换了旧样式,不建议将表作为FROM子句中的逗号分隔列表连接到适当的INNER JOIN子句,并为表分配别名。

答案 2 :(得分:0)

您可以使用rank()对价格的总和进行排名,首先是更昂贵的价格。

SELECT category,
       price
       FROM (SELECT category,
                    sum(tickets.price) price,
                    rank() OVER (ORDER BY sum(tickets.price) DESC) r
                    FROM tickets
                         INNER JOIN transactions  
                                    ON transactions.ticket_num = tickets.ticket_num
                    GROUP BY category) x
       WHERE r = 1;

我还自由地将您的联接从古老的逗号样式重写为现代,更清晰的版本。