[英]Ranking before grouping problem in SQL Server 2005
HI,
這應該很容易,但我對分組的工作原理還不夠了解。
基本上我有2個表“類別”和“項目”
分類
ID
分類名稱
項目
ID
CategoryID ItemName
照片
得分
我想要做的就是為每個類別獲得1行,其中包含類別ID,類別名稱和屬於最高得分項目的照片。
所以我嘗試通過CategoryID將類別加入項目和分組。 麻煩的是,我想訂購物品,以便在進行分組之前,最高得分項目位於頂部,以確保照片來自該類別中當前得分最高的項目。 如果我選擇MAX(I.score)我可以獲得最高分,但我不知道如何獲得附帶照片,因為MAX(照片)顯然會按字母順序給我帶有最高文件名的照片。
我希望我已經解釋得那么好。
你可以嘗試一下(完整的例子)
DECLARE @Categories TABLE(
ID INT,
CategoryName VARCHAR(50)
)
DECLARE @Items TABLE(
ID INT,
CategoryID INT,
ItemName VARCHAR(50),
Photo VARCHAR(50),
Score FLOAT
)
INSERT INTO @Categories (ID,CategoryName) SELECT 1, 'Cat1'
INSERT INTO @Categories (ID,CategoryName) SELECT 2, 'Cat2'
INSERT INTO @Items (ID,CategoryID,ItemName,Photo,Score) SELECT 1, 1, 'Item1', 'PItem1', 1
INSERT INTO @Items (ID,CategoryID,ItemName,Photo,Score) SELECT 2, 1, 'Item2', 'PItem2', 2
INSERT INTO @Items (ID,CategoryID,ItemName,Photo,Score) SELECT 3, 1, 'Item3', 'PItem3', 3
INSERT INTO @Items (ID,CategoryID,ItemName,Photo,Score) SELECT 4, 2, 'Item4', 'PItem4', 5
INSERT INTO @Items (ID,CategoryID,ItemName,Photo,Score) SELECT 5, 2, 'Item5', 'PItem5', 2
SELECT *
FROM (
SELECT c.ID,
c.CategoryName,
i.Photo,
i.Score,
ROW_NUMBER() OVER(PARTITION BY i.CategoryID ORDER BY i.Score DESC) RowID
FROM @Categories c INNER JOIN
@Items i ON c.ID = i.CategoryID
) CatItems
WHERE RowID = 1
使用ROW_NUMBER,您可以選擇所需的項目。
您需要首先聚合並像這樣加入。 (如果更改分組,則需要更改JOIN)
SELECT
...
FROM
(
select
max(Score) AS MaxScore,
CategoryID
FROM
Items
GROUP BY
CategoryID
) M
JOIN
Items I ON M.CategoryID = I.CategoryID AND M.MaxScore = I.Score
JOIN
Categories C ON I.CategoryID = C.CategoryID
這是一個非常常見的問題,也是SQL Server無法解決的問題。 不過這樣的事情可以解決問題:
select
c.ID,
c.CategoryName,
item.*
from Categories c
join (
select
ID,
CategoryID,
ItemName,
Photo,
Score,
(row_number() over order by CategoryID, Score desc) -
(rank() over order by CategoryID) as rownum
from Items) item on item.CategoryID = c.CategoryID and item.rownum = 0
雖然沒有明確的group by
子句,但是(出於實際目的)將Categories
記錄分組並為您提供一個join
ed語句,允許您查看最高得分項的任何屬性。
您可以使用行號對每個類別的項目進行排名:
select *
from (
select
row_number() over (partition by c.id order by i.score desc) rn
, *
from Categories c
join Items i on c.ID = i.CategoryID
) sub
where rn = 1
在SQL 2005中,您不能直接在where
引用row_number()
,因此它包含在子查詢中。
正如你所說的那樣:“類別ID,類別名稱和屬於最高得分項目的照片。” - 現在我猜測你真的是“......那個類別中得分最高的項目”,不是嗎?)
Select CategoryID, c.Categoryname, Photo
From items i Join Categoiries c
On c.ID = i.CategoryId
Where Score = (Select Max(Score) From Items
Where CategoryID = i.CategoryId)
如果你真的意味着整個項目表中得分最高的項目,那么只需省略子查詢中的謂詞
Select CategoryID, c.Categoryname, Photo
From items i Join Categoiries c
On c.ID = i.CategoryId
Where Score = (Select Max(Score) From Items)
如果定義的組中有多個項目與最高分數相關,則這兩個查詢都將返回每個組的多個行。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.