2012-07-25 90 views
1
CREATE TABLE Items 
(
    ItemId INT NOT NULL, 
    CategoryId INT NOT NULL, 
    ItemValue INT NOT NULL 
) 

表中包含項目。每個項目都屬於一個類別並存儲一些數字值。基於另一列上的條件從組中提取值

作爲查詢的結果,我希望每行代表一個類別。應該有三列:

  • category id;
  • 每個類別中具有最高ItemValue的項目的ID;
  • 每個類別具有最低ItemValue的項目的ID。

查詢的性能很重要。我使用MS SQL Server。

回答

2

對於SQL Server 2005 +,你可以這樣做:

;WITH CTE AS 
(
    SELECT *, 
      ROW_NUMBER() OVER(PARTITION BY CategoryId ORDER BY ItemValue DESC) MaxRN, 
      ROW_NUMBER() OVER(PARTITION BY CategoryId ORDER BY ItemValue) MinRN 
    FROM Items 
) 
SELECT CategoryId, 
     MIN(CASE WHEN MaxRN = 1 THEN ItemId END) IdMaxValue, 
     MIN(CASE WHEN MinRN = 1 THEN ItemId END) IdMinValue 
FROM CTE 
GROUP BY CategoryId; 

這裏是一個fiddle在那裏你可以測試這個解決方案。

+0

這很好,謝謝! – 2012-07-25 14:30:55

1

我想嘗試的公共表表達式:

WITH CategoryHigh (High, ItemId, CategoryId) 
AS 
(
SELECT 
    ROW_NUMBER() OVER (PARTITION BY CategoryId ORDER BY ItemValue DESC) AS High, 
    ItemId, 
    CategoryId 
FROM Items 
), 
CategoryLow (Low, ItemId, CategoryId) 
AS 
(
SELECT 
    ROW_NUMBER() OVER (PARTITION BY CategoryId ORDER BY ItemValue) AS Low, 
    ItemId, 
    CategoryId 
FROM Items 
) 
SELECT 
H.CategoryId, 
L.ItemId AS LowItem, 
H.ItemId AS HighItem 
FROM CategoryHigh H 
JOIN CategoryLow L ON H.CategoryId = L.CategoryId 
WHERE H.High = 1 AND 
     L.Low = 1 
+0

謝謝,這個作品!雖然,拉馬克的解決方案似乎表現更好,而且它也更短,所以我將他的答案標記爲已接受。 – 2012-07-25 14:32:04

+0

是的,我很高興看到他的回答,因爲我開始時試圖在一個CTE中同時具有Row_Number()函數,但是無法從此處開始工作。儘管感謝您的認可! – Aushin 2012-07-25 14:33:23

1

試試這個:

;with 
cte as(
    select *,ROW_NUMBER() over(partition by [CategoryId] order by [ItemValue]) rownum 
    from [Items]), 
cte1 as(select [CategoryId],MIN([ItemId]) [min_ItemId] 
    from cte where rownum=1 
    group by [CategoryId]), 
cte2 as(
    select *,ROW_NUMBER() over(partition by [CategoryId] order by [ItemValue]) rownum 
    from [Items]), 
cte3 as( 
    select [CategoryId],MAX([ItemId]) [max_ItemId] 
    from cte2 C1 
    where rownum=(select MAX(rownum) from cte C2 where C1.[CategoryId]=C2.[CategoryId]) 
    group by [CategoryId]) 
select A.[CategoryId],A.[min_ItemId],B.[max_ItemId] 
from cte1 A join cte3 B 
on A.[CategoryId]=B.[CategoryId] 
相關問題