我有这个日期
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
所需的输出
我当前的查询是
SELECT
*
,ROW_NUMBER()OVER(PARTITION BY CAST(ID AS VARCHAR(2))+Items ORDER BY Items DESC) AS RN
FROM @tbl
ORDER BY ID,Items
答案 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;