Mysql 涉及MAX()的更简洁的SQL查询
我只想退回那些电影排队最贵的订阅者,如果你在某个特定时间丢失了所有的电影,我想退回Netflix DVD的更换费用。我使用MAX而不是TOP、LIMIT或ROWNUM,因为查询需要尽可能独立于db,并且在出现平局时必须返回多个订阅者。使用上表,结果应为 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 | +-----------------+-----------+------------------+ 经过大量的搜索和实验,我已经找到了可以工作的代码,但在我的新手看来,无论是在代码数量还是执行方面,它都显得臃肿而低效 有人介意重构和解释你的代码吗 我的代码: 在sql示例的查询中,有些列名不同,因此我使用了演示表中给出的列名。我在内部查询中使用秩函数,以替换价格之和查找所有订购人员的订单。然后选择排名为1的行Mysql 涉及MAX()的更简洁的SQL查询,mysql,sql,sql-server,subquery,max,Mysql,Sql,Sql Server,Subquery,Max,我只想退回那些电影排队最贵的订阅者,如果你在某个特定时间丢失了所有的电影,我想退回Netflix DVD的更换费用。我使用MAX而不是TOP、LIMIT或ROWNUM,因为查询需要尽可能独立于db,并且在出现平局时必须返回多个订阅者。使用上表,结果应为 inventory +------------------+-------------------+------------+ | DVD | replacement_price | stock | +----
Rank在MS Sql Server和Oracle中都可用。如@bluefeet所说,您需要提供更多关于目标数据库的详细信息。如果您只想返回最大总数的数据库,那么您可以使用以下在MySQL和SQL Server中都适用的方法。但它并不比您当前的查询更简洁:
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 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);
请参见请通过添加适当的标记Oracle、SQL Server、MySQL等来指定您要针对的RDBMS。。可能有一些答案利用了并非普遍支持的语言或产品功能。此外,通过使用特定的RDBMS标记它,您的问题可能会得到更适合回答它的人的注意。如果可能,我希望该查询同时在MySQL和SQL Server上工作;很抱歉,非常感谢你的帮助。不幸的是,我被叫走了,所以我今天晚些时候必须尝试你的查询。我是一个如此无知的人,我以为你在写[r]ank时把MySQL称为Oracle,因为它在MS SQL Server和Oracle中都可用。我花了一分钟的时间才意识到我的错误,搜索MySQL排名函数的结果是空的。我不想把自己局限于MySQL,所以看看如何在SQLServer中实现它仍然很有帮助。在将您的查询粘贴到sqlfiddle之后,我确实注意到了,直到BlueFoots在其回复中提到ORDER BY子句需要DESC关键字才能获取顶部而不是底部的订阅者,我才知道存在sqlfiddle。谢谢。我很早就被叫去上班了,但我会尽快检查你的代码。谢谢你的全面回复。我仅仅用SQL进行了几天的黑客攻击,只是在我的MBP上预装了MySQL 5.5;看到我解决的问题的替代解决方案非常有帮助,特别是当这些问题是由真正知道自己在做什么的人写的时候。您的MySQL查询可能并不更简洁,但它比我的更可读,并且SQL Server查询非常干净。还感谢Fiddle link,我还没有找到这样的草稿本来使用不同的RDBMS。谢谢你抽出时间。
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
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);
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