SQL Server комплексный рейтинг - PullRequest
4 голосов
/ 21 июня 2019

У меня есть эта дата

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 ]

2 голосов
/ 21 июня 2019

Если я правильно понимаю вашу логику, следующий подход может помочь. Appraoch использует два отдельных 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
0 голосов
/ 21 июня 2019

Пожалуйста, смотрите ниже запрос, основная часть ранжирования выполняется с помощью функции dens_rank, затем исключения, такие как значение B для идентификатора 2, которое может быть равно 1 или 2, и C для идентификатора 3, который может быть равен 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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...