0
存货
+------------------+------------------+---------- --+
| 影碟 | 更换价格 | 库存|
+------------------+------------------+---------- --+
| 圆周率 | 9.99 | 500 |
| 沙丘 | 29.99 | 100 |
| 希瑟斯 | 4.99 | 20 |
| 大白鲨 | 19.99 | 500 |
| Mulholland_Drive | 39.99 | 50 |
| 醒来_生活 | 29.99 | 200 |
+------------------+------------------+---------- --+

租用
+-----------------+------------+------------------+
| 订户 | queue_nbr | 影碟 |
+-----------------+------------+------------------+
| 鲍勃 | 1 | Mulholland_Drive |
| 鲍勃 | 2 | 大白鲨 |
| 蔡 | 1 | 圆周率 |
| 蔡 | 2 | 希瑟斯 |
| 杰米 | 2 | Mulholland_Drive |
| 杰米 | 4 | 沙丘 |
| 杰米 | 1 | 大白鲨 |
| 杰米 | 3 | 醒来_生活 |
| 诺拉 | 4 | 大白鲨 |
| 诺拉 | 2 | Mulholland_Drive |
| 诺拉 | 3 | 沙丘 |
| 诺拉 | 1 | 醒来_生活 |
+-----------------+------------+------------------+

我只想返回具有最昂贵电影队列的订户(如果您在给定时间丢失了所有电影,请考虑 Netflix DVD 更换成本)。我使用了 MAX() 而不是 TOP、LIMIT 或 ROWNUM,因为查询需要尽可能独立于数据库,并且在出现平局时必须返回多个订阅者。使用上面的表格,结果应该是

+----------+
| 最高 |
+----------+
| 杰米 |
| 诺拉 |
+----------+

经过大量的搜索和实验,我提出了可行的代码,但在我的新手眼中,无论是在代码数量还是在执行方面,它都显得臃肿且效率低下。

有人介意重构和解释您的代码吗?

我的代码:


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

4

2 回答 2

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 的行。

Rank 在 MS Sql Server 和 Oracle 中都可用。要比@bluefeet 所说的更进一步,您需要提供更多关于您所针对的数据库的详细信息。

于 2013-03-13T11:41:11.340 回答
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

请参阅带有演示的 SQL Fiddle

于 2013-03-13T11:45:42.457 回答