簡體   English   中英

在SQL Server 2005中分組問題之前的排名

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM