これは関係除算です:リンク1、リンク2。
除数テーブル(食品と飲料のみ)が静的である場合は、次のいずれかのソリューションを使用できます。
DECLARE @OrderDetail TABLE
([OrderID] int, [Name] varchar(8), [Type] varchar(8), [Price] decimal(10,2))
;
INSERT INTO @OrderDetail
([OrderID], [Name], [Type], [Price])
SELECT 1, 'Broccoli', 'Food', 1.0
UNION ALL SELECT 1, 'Beer', 'Beverage', 5.0
UNION ALL SELECT 1, 'Coke', 'Beverage', 2.0
UNION ALL SELECT 2, 'Beef', 'Food', 2.5
UNION ALL SELECT 2, 'Juice', 'Beverage', 1.5
UNION ALL SELECT 3, 'Beer', 'Beverage', 5.0
UNION ALL SELECT 4, 'Tomato', 'Food', 1.0
UNION ALL SELECT 4, 'Apple', 'Food', 1.0
UNION ALL SELECT 4, 'Broccoli', 'Food', 1.0
-- Solution 1
SELECT od.OrderID,
COUNT(DISTINCT od.Type) AS DistinctTypeCount,
MAX(CASE WHEN od.Type='beverage' THEn od.Price END) AS MaxBeveragePrice
FROM @OrderDetail od
WHERE od.Type IN ('food', 'beverage')
GROUP BY od.OrderID
HAVING COUNT(DISTINCT od.Type) = 2 -- 'food' & 'beverage'
-- Solution 2: better performance
SELECT pvt.OrderID,
pvt.food AS MaxFoodPrice,
pvt.beverage AS MaxBeveragePrice
FROM (
SELECT od.OrderID, od.Type, od.Price
FROM @OrderDetail od
WHERE od.Type IN ('food', 'beverage')
) src
PIVOT ( MAX(src.Price) FOR src.Type IN ([food], [beverage]) ) pvt
WHERE pvt.food IS NOT NULL
AND pvt.beverage IS NOT NULL
結果(ソリューション1および2の場合):
OrderID DistinctTypeCount MaxBeveragePrice
----------- ----------------- ---------------------------------------
1 2 5.00
2 2 1.50
Table 'Worktable'. Scan count 2, logical reads 23, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table '#09DE7BCC'. Scan count 1, logical reads 1, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
OrderID MaxFoodPrice MaxBeveragePrice
----------- --------------------------------------- ---------------------------------------
1 1.00 5.00
2 2.50 1.50
Table '#09DE7BCC'. Scan count 1, logical reads 1, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.