0
在庫
+--------------------+-------------------+---------------------- --+
| | DVD | 交換価格 | 在庫 |
+--------------------+-------------------+---------------------- --+
| | 円周率 | パイ | 9.99 | 500 |
| | 砂丘 | 29.99 | 100 |
| | ヘザーズ | 4.99 | 20 |
| | あご | ジョーズ 19.99 | 500 |
| | マルホランド ドライブ | 39.99 | 50 |
| | ウェイクライフ | 29.99 | 200 |
+--------------------+-------------------+---------------------- --+

借りた
+-----------------+-----------------------+------------------+
| | 加入者 | queue_nbr | DVD |
+-----------------+-----------------------+------------------+
| | ボブ | 1 | マルホランド ドライブ |
| | ボブ | 2 | あご | ジョーズ
| | チェイ | 1 | 円周率 | パイ |
| | チェイ | 2 | ヘザーズ |
| | ジェイミー | 2 | マルホランド ドライブ |
| | ジェイミー | 4 | 砂丘 |
| | ジェイミー | 1 | あご | ジョーズ
| | ジェイミー | 3 | ウェイクライフ |
| | ノラ | 4 | あご | ジョーズ
| | ノラ | 2 | マルホランド ドライブ |
| | ノラ | 3 | 砂丘 |
| | ノラ | 1 | ウェイクライフ |
+-----------------+-----------------------+------------------+

最も高価な映画のキューを持つサブスクライバーのみを返したいです (特定の時間に持っていたすべての映画を失った場合の Netflix DVD の交換費用を考えてください)。TOP、LIMIT、または ROWNUM ではなく MAX() を使用しました。これは、クエリが可能な限りデータベースに依存しないようにする必要があり、引き分けの場合に複数のサブスクライバーを返す必要があるためです。上記の表を使用すると、結果は次のようになります。

+---------+
| | 最高 |
+---------+
| | ジェイミー |
| | ノラ |
+---------+

多くの検索と実験の後、機能するコードを思いつきましたが、コードの量と実行の両方で、初心者の目には肥大化して非効率的であるように見えます。

あなたのコードをリファクタリングして説明してくれる人はいますか?

私のコード:


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

合計を含むものだけを返したい場合はmax、MySQLとSQLServerの両方で機能する次のものを使用できます。ただし、現在のクエリほど簡潔ではありません。

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 FiddlewithDemoを参照してください

于 2013-03-13T11:45:42.457 に答える
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の行を選択します。

ランクは、MSSqlServerとOracleの両方で使用できます。@bluefeetが言うように、それよりもはるかに先に進むには、ターゲットにしているデータベースについてより詳細に説明する必要があります。

于 2013-03-13T11:41:11.340 に答える