在 Table 的组列中查找最高和最低

Find Top Most AND Lowest In a Table's Group Column

我有一个 table,里面有 4 个字段,ID, Price, QTY, Ratting 和可选的 [Position]。

我有所有按列分组的记录 [Qty,Ratting]

我必须定义 groupwise 的位置并将该位置存储到可选列中。

为了更好地理解,我在 table:

中添加了一张包含数据的图像

QTY的基础上,在每个Rating中,我要标记Top3, Bottom3 and Rest of them as remaining.

我不知道该怎么做。

有人可以建议我怎么做吗? 到目前为止,我尝试过的是:

Declare @RankTable TABLE 
(
    ID INT,
    Price Decimal (10,2),
    Qty INT,
    Ratting INT
)
INSERT INTO @RankTable 
SELECT 1,10,15,1
UNION ALL
SELECT 2,11,11,1
UNION ALL
SELECT 3,96,10,1
UNION ALL
SELECT 4,96,8,1
UNION ALL
SELECT 5,56,7,1
UNION ALL
SELECT 6,74,5,1
UNION ALL
SELECT 7,93,4,1
UNION ALL
SELECT 8,98,2,1
UNION ALL
SELECT 9,12,1,1

UNION ALL
SELECT 10,32,80,2
UNION ALL
SELECT 11,74,68,2
UNION ALL
SELECT 12,58,57,2
UNION ALL
SELECT 13,37,43,2
UNION ALL
SELECT 14,79,32,2
UNION ALL
SELECT 15,29,28,2
UNION ALL
SELECT 16,46,17,2
UNION ALL
SELECT 17,86,13,2

UNION ALL
SELECT 19,75,110,3
UNION ALL
SELECT 20,27,108,3
UNION ALL
SELECT 21,38,104,3
UNION ALL
SELECT 22,87,100,3
UNION ALL
SELECT 23,47,89,3
DECLARE @PositionGroup VARCHAR(1)
SELECT *,ISNULL(@PositionGroup,'') AS Position FROM @RankTable

使用Window Function。试试这个。

;WITH cte
     AS (SELECT *,
                Row_number()OVER(partition BY rating ORDER BY id)         rn,
                count(id)OVER(partition BY rating) mx
         FROM   @RankTable)
SELECT ID,
       Price,
       Qty,
       Rating,
        mx - rn,
       CASE WHEN rn IN ( 1, 2, 3 ) THEN 0
            WHEN mx - rn IN( 0, 1, 2 ) THEN 1
         ELSE 2
       END position
FROM   cte 

你可以试试这个:

SELECT ID
      ,Price
      ,Qty
      ,Ratting
      ,CASE WHEN RowID >= 1 AND RowID <= 3 
            THEN 0 
       ELSE CASE WHEN RowID > Total - 3 THEN 1 ELSE 2 END END AS Position
FROM (SELECT ID
            ,Price
            ,Qty
            ,Ratting
            ,COUNT(*) OVER(PARTITION BY Ratting) AS Total
            ,ROW_NUMBER() OVER(PARTITION BY Ratting ORDER BY Qty DESC) AS RowID
            ,ISNULL(@PositionGroup,'') AS Position
      FROM @RankTable) AS T

也试试这个。

;WITH cte AS 
(
SELECT  MAX(Row) [Max],
        MIN(Row) [Min],
        LU.Ratting 
FROM    (
        SELECT  *,
                ROW_NUMBER() OVER(PARTITION BY Ratting ORDER BY Qty DESC) Row 
        FROM    @RankTable)LU
        GROUP BY LU.Ratting
        ) 

SELECT  ID,
        R.Price,
        R.Qty,
        cte.Ratting,
        CASE WHEN (Row - Min) <= 2 THEN 0 WHEN (Max - Row) <= 2 THEN 1 ELSE 2 END Position 
FROM    cte 
JOIN    (
        SELECT  Ratting,
                ID,
                Price,
                Qty,
                ROW_NUMBER() OVER(PARTITION BY Ratting ORDER BY Qty DESC) [Row] 
        FROM    @RankTable
        ) R ON R.Ratting = cte.Ratting

结果: