14

私はノースウィンド データベースを使用して、多かれ少なかれ複雑なクエリを作成することで、SQL スキルを更新しています。残念ながら、最後のユース ケース「1997 年のすべてのカテゴリの上位 5 つの注文の合計を取得する」の解決策を見つけることができませんでした。

関連するテーブルは次のとおりです。

Orders(OrderId, OrderDate)
Order Details(OrderId, ProductId, Quantity, UnitPrice)
Products(ProductId, CategoryId)
Categories(CategoryId, CategoryName)

次のクエリを試しました

SELECT c.CategoryName, SUM(
  (SELECT TOP 5 od2.UnitPrice*od2.Quantity 
   FROM [Order Details] od2, Products p2
   WHERE od2.ProductID = p2.ProductID
   AND c.CategoryID = p2.CategoryID
   ORDER BY 1 DESC))
FROM [Order Details] od, Products p, Categories c, Orders o 
WHERE od.ProductID = p. ProductID
AND p.CategoryID = c.CategoryID
AND od.OrderID = o.OrderID
AND YEAR(o.OrderDate) = 1997
GROUP BY c.CategoryName

ええと...集計関数ではサブクエリが許可されていないことが判明しました。この問題に関する他の投稿を読みましたが、特定のユース ケースの解決策が見つかりませんでした。あなたが私を助けてくれることを願っています...

4

4 に答える 4

34

サブクエリは通常、集計関数では許可されていません。代わりに、集計をサブクエリ内に移動します。この場合、次の理由により、追加レベルのサブクエリが必要になりますtop 5

SELECT c.CategoryName,
  (select sum(val)
   from (SELECT TOP 5 od2.UnitPrice*od2.Quantity as val
         FROM [Order Details] od2, Products p2
         WHERE od2.ProductID = p2.ProductID
         AND c.CategoryID = p2.CategoryID
         ORDER BY 1 DESC
        ) t
  )
FROM [Order Details] od, Products p, Categories c, Orders o 
WHERE od.ProductID = p. ProductID
AND p.CategoryID = c.CategoryID
AND od.OrderID = o.OrderID
AND YEAR(o.OrderDate) = 1997
GROUP BY c.CategoryName, c.CategoryId
于 2013-05-01T13:28:52.867 に答える
4

過度のサブクエリの代わりに、 ROW_NUMBERランキング関数でCTEを使用します。

 ;WITH cte AS
 (
  SELECT c.CategoryName, od2.UnitPrice, od2.Quantity,
         ROW_NUMBER() OVER(PARTITION BY c.CategoryName ORDER BY od2.UnitPrice * od2.Quantity DESC) AS rn
  FROM [Order Details] od JOIN Products p ON od.ProductID = p.ProductID
                          JOIN Categories c ON p.CategoryID = c.CategoryID
                          JOIN Orders o ON od.OrderID = o.OrderID
  WHERE o.OrderDate >= DATEADD(YEAR, DATEDIFF(YEAR, 0, '19970101'), 0)
    AND o.OrderDate < DATEADD(YEAR, DATEDIFF(YEAR, 0, '19970101')+1, 0)
  )
  SELECT CategoryName, SUM(UnitPrice * Quantity) AS val
  FROM cte
  WHERE rn < 6
  GROUP BY CategoryName
于 2013-05-01T14:23:32.087 に答える
0

レコードが日付でソートされている Access サブクエリで、非常によく似た問題に遭遇しました。「Last」集計関数を使用すると、すべてのサブクエリを通過し、Access テーブルからデータの最後の行が取得されましたが、意図したとおりに並べ替えられたクエリではありませんでした。最初の括弧内で集計関数を使用するようにクエリを書き直すこともできましたが (以前に提案されたように)、クエリ結果をデータベース内のテーブルとして、必要な順序で並べ替えて保存し、"最後の" 必要な値を取得する集計関数。結果を最新の状態に保つために、今後更新クエリを実行します。効率的ではありませんが、効果的です。

于 2015-04-10T20:52:15.933 に答える