我有两个桌子。一个是交易,另一个是门票。在门票中,我有门票编号,类别名称(剧院,电影院,音乐会),门票价格。在交易中,我也有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个或多个值可以相同
答案 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;
我还自由地将您的联接从古老的逗号样式重写为现代,更清晰的版本。