inventory +------------------+-------------------+------------+ | DVD | replacement_price | stock | +------------------+-------------------+------------+ | Pi | 9.99 | 500 | | Dune | 29.99 | 100 | | Heathers | 4.99 | 20 | | Jaws | 19.99 | 500 | | Mulholland_Drive | 39.99 | 50 | | Waking_Life | 29.99 | 200 | +------------------+-------------------+------------+ rented +-----------------+-----------+------------------+ | subscriber | queue_nbr | DVD | +-----------------+-----------+------------------+ | Bob | 1 | Mulholland_Drive | | Bob | 2 | Jaws | | Chey | 1 | Pi | | Chey | 2 | Heathers | | Jamie | 2 | Mulholland_Drive | | Jamie | 4 | Dune | | Jamie | 1 | Jaws | | Jamie | 3 | Waking_Life | | Nora | 4 | Jaws | | Nora | 2 | Mulholland_Drive | | Nora | 3 | Dune | | Nora | 1 | Waking_Life | +-----------------+-----------+------------------+
我想只返回拥有最昂贵电影队列的订阅者(如果您丢失了在给定时间播放的所有电影,请考虑Netflix DVD更换费用)。我使用MAX()而不是TOP,LIMIT或ROWNUM,因为查询需要尽可能与数据库无关,并且必须在出现平局时返回多个订阅者。使用上面的表格,结果应为
+---------+ | highest | +---------+ | Jamie | | Nora | +---------+
经过大量的搜索和实验,我提出了可行的代码,但在新手眼中,无论是代码还是执行,我看起来都是臃肿而低效的。
有人会介意重构和解释您的代码吗?
我的代码:
SELECT z.subscriber highest
FROM
(SELECT MAX(price) max_price
FROM (
SELECT subscriber_name subscriber, SUM(replacement_price) price
FROM inventory i
INNER JOIN rented r
ON i.DVD = r.DVD
GROUP BY subscriber
) x
) y
INNER JOIN
(
SELECT subscriber_name subscriber, SUM(replacement_price) price
FROM inventory i
INNER JOIN rented r
ON i.DVD = r.DVD
GROUP BY subscriber
) z
ON z.price = y.max_price
答案 0 :(得分:0)
SELECT z.subscriber
FROM(
SELECT RANK() OVER(ORDER BY SUM(replacement_price)) subscriber_rank,
r.subscriber subscriber,
SUM(replacement_price) totalReplacementPrice
FROM inventory i
INNER JOIN rented r ON i.dvd = r.DVD
GROUP BY subscriber
) z
WHERE z.subscriber_rank = 1
您从sql示例查询时,有些列名称不同,所以我使用了演示表中给出的列名。我在内部查询中使用rank函数来查找按replacement_price的总和排序的所有人的顺序。然后选择排名为1的行。
排名在MS Sql Server和Oracle中均可用。要比@bluefeet更进一步说明你需要提供更多关于你所针对的数据库的详细信息。
答案 1 :(得分:0)
如果您只想返回总数为max
的那些,那么您可以使用以下适用于MySQL和SQL Server的方法。它不比你当前的查询更简洁:
select subscriber
from inventory i
inner join rented r
on i.dvd = r.dvd
group by subscriber
having sum(replacement_price) = (select max(TotalCost)
from
(
select sum(replacement_price) TotalCost
from inventory i
inner join rented r
on i.dvd = r.dvd
group by subscriber
) p);
如果您使用的是SQL Server,那么我建议实现窗口函数,类似于:
select subscriber
from
(
select subscriber,
rank() over(order by sum(replacement_price) desc) rnk
from inventory i
inner join rented r
on i.dvd = r.dvd
group by subscriber
) src
where rnk = 1