1

以下の1つの製品アイテムごとに合計金額を計算するクエリがあります。

SELECT p.[Id], COUNT(o.[Id]), SUM(o.[Amount])
FROM [dbo].[Order] o
    INNER JOIN [dbo].[Product] p ON p.[Id] = o.[ProductId]
GROUP BY p.[Id]

この場合、COUNT(o.[Id]) は、1 つの商品アイテムごとの一意の注文数です。

しかし、COUNT(o.[Id]) の代わりに、次の式を使用して注文数を計算したいと思います。

COUNT(o.[OwnerId]) -- where o.[OwnerId] IS NOT NULL
+
COUNT(o.[Id]) -- where o.[OwnerId] IS NULL

1 つのクエリで実装できますか? パフォーマンスが向上するソリューションはどれですか?

アップデート:

急いで仕上げてしまい、大変申し訳ありません。Mahmoud Gamal は良い例を提供していますが、計算方法が少し異なります。

SELECT
    p.[Id],
    COUNT(DISTINCT CASE WHEN o.[OwnerId] IS NOT NULL THEN o.[OwnerId] ELSE NULL END) AS [NumberOfOrderOwners],
    SUM(CASE WHEN o.[OwnerId] IS NULL THEN 1 ELSE 0 END) AS [NumberOfAnonimousOwners],
    SUM(o.[Amount])
FROM [dbo].[Order] o
    INNER JOIN [dbo].[Product] p ON p.[Id] = o.[ProductId]
GROUP BY p.[Id]

上記のクエリは必要に応じて計算しますが、COUNT 内で DISTINCT を使用しているため、推定コストが 2 倍になります。

クエリを改善するために誰か助けてもらえますか?

4

1 に答える 1

2

これを試して:

SELECT 
  p.[Id],
  SUM(CASE WHEN o.[OwnerId] IS NOT NULL THEN 1 ELSE 0 END) +
  SUM(CASE WHEN o.[Id]      IS NULL     THEN 1 ELSE 0 END) AS Total
FROM [dbo].[Order] o
INNER JOIN [dbo].[Product] p ON p.[Id] = o.[ProductId]
GROUP BY p.[Id]
于 2013-03-28T08:57:16.117 に答える