SQL Server综合排名

时间:2019-06-21 07:54:09

标签: sql-server tsql

我有这个日期

DECLARE @tbl table (ID INT, Items VARCHAR(5))
INSERT INTO  @tbl VALUES
(1,'A'),(1,'A'),(1,'A'),(1,'B'),(1,'D'),(2,'A'),(2,'A'),(2,'B'),
(2,'B'),(2,'B'),(3,'A'),(3,'A'),(3,'B'),(3,'B'),(3,'C'),(3,'C'),
(3,'C'),(3,'E'),(3,'F')

我想要的是在ID 1中有3个不同的项目A,B和C,所有重复项(例如A)都排在第1位,B和C没有重复项,所以分别排在第2位和第3位 在ID 2中,有2个不同的项目A和B,A为1,下一个项目B将为1,直到项目B的最后一个值为2,以此类推

当前输出

ID  Items   RN
1   A       1
1   A       2
1   A       3
1   B       1
1   D       1
2   A       1
2   A       2
2   B       1
2   B       2
2   B       3
3   A       1
3   A       2
3   B       1
3   B       2
3   C       1
3   C       2
3   C       3
3   E       1
3   F       1

所需的输出

enter image description here

我当前的查询是

SELECT
*
,ROW_NUMBER()OVER(PARTITION BY  CAST(ID AS VARCHAR(2))+Items  ORDER BY  Items DESC)  AS RN
FROM @tbl
ORDER BY ID,Items

2 个答案:

答案 0 :(得分:2)

如果我正确理解您的逻辑,则下一种方法可能会有所帮助。该方案使用两个独立的CTE来编号唯一和不唯一的序列。

表格:

DECLARE @tbl table (ID INT, Items VARCHAR(5))
INSERT INTO  @tbl VALUES
(1,'A'),(1,'A'),(1,'A'),(1,'B'),(1,'D'),(2,'A'),(2,'A'),(2,'B'),
(2,'B'),(2,'B'),(3,'A'),(3,'A'),(3,'B'),(3,'B'),(3,'C'),(3,'C'),
(3,'C'),(3,'E'),(3,'F')

T-SQL:

;WITH NotUniqueCTE AS (
    SELECT 
        ID,
        Items,
        CASE 
            WHEN COUNT(*) OVER (PARTITION BY ID, Items) > 1 THEN 0
            ELSE 1
        END AS Item_Unique,
        CASE 
            WHEN 
                (Items <> 'A') AND 
                (COUNT(*) OVER (PARTITION BY ID, Items) = ROW_NUMBER() OVER (PARTITION BY ID, Items ORDER BY Items DESC)) THEN 2 
            ELSE 1 
        END AS RN_NotUnique
    FROM @tbl
), UniqueCTE AS (
    SELECT 
        *,
        DENSE_RANK() OVER (PARTITION BY ID ORDER BY Item_Unique DESC, Items) +
        MAX(CASE WHEN Item_Unique = 0 THEN RN_NotUnique END) OVER (PARTITION BY ID)
        AS RN_Unique
    FROM NotUniqueCTE
)
SELECT 
    ID,
    Items,
    CASE
        WHEN Item_Unique = 1 THEN RN_Unique
        ELSE RN_NotUnique
    END AS RN
FROM UniqueCTE
ORDER BY ID, Items

输出:

ID  Items   RN
1   A       1
1   A       1
1   A       1
1   B       2
1   D       3
2   A       1
2   A       1
2   B       1
2   B       1
2   B       2
3   A       1
3   A       1
3   B       1
3   B       2
3   C       1
3   C       1
3   C       2
3   E       3
3   F       4

答案 1 :(得分:-1)

请参阅下面的查询,排名的大部分操作是使用density_rank函数完成的,然后可以使用以下方法处理ID 2上的B值可以为1或2以及ID 3的C可以为1或2的异常第二名。

DECLARE @tbl table (ID INT, Items VARCHAR(5))
INSERT INTO  @tbl VALUES
(1,'A'),(1,'A'),(1,'A'),(1,'B'),(1,'D'),(2,'A'),(2,'A'),(2,'B'),
(2,'B'),(2,'B'),(3,'A'),(3,'A'),(3,'B'),(3,'B'),(3,'C'),(3,'C'),
(3,'C'),(3,'E'),(3,'F')


select case when items='C' and rowno in (1, 2) then 1 when Items='B' and rowno in (2, 3) then 1 when ID=3 and Items='B' and rowno=5 then 1 when ID=3 and Items='C' and rowno=3 then 2
when Items='E' then 3 when Items='F' then 4 else rn end as rn, ID, rowno, Items from 
(
select ROW_NUMBER()over(PARTITION by items order by id) rowno, DENSE_RANK()over(partition by id 
order by items) rn, * from @tbl
) x
order by ID, Items;

oa