Как разделить, чтобы распространять значения? - PullRequest
2 голосов
/ 28 мая 2019

У меня есть таблица с данными:

Клиенты

  • Последовательность
  • ID
  • много других столбцов (не важно)

Пример данных:

Sequence ID
-----------
214906 2613
214906 2614
214906 2615
214907 2613
214907 2614
214907 2615
214908 2613
214908 2614
214908 2615
214000 2613
213004 4444
111111 5555
111111 5556
111112 5556 
111112 5555

Как получить желаемый результат ниже?

214906 2613
214907 2614
214908 2615
214000 2613
213004 4444
111111 5555
111112 5556

Я пробовал разные вещи с ROW_NUMBER() OVER(PARTITION BY Sequence), но это не помогло, потому чтоМне нужно взять строку 1 в первой группе, строку 2 во второй группе и т. Д. Другими словами, мне нужно как-то распределить эти последовательности по идентификаторам.Я также не могу разделить по идентификаторам, потому что они могут появляться более одного раза в таблице

1 Ответ

2 голосов
/ 28 мая 2019

Надеюсь, я вас правильно понял.Я использую количество идентификаторов для каждой последовательности в качестве группового фактора (используя SUM() с предложением OVER без ORDER BY) и после этого соответствующего ранжирования и нумерации строк:

Ввод:

CREATE TABLE #Data (
    Sequence int,
    ID int
)
INSERT INTO #Data 
    (Sequence, ID)
VALUES
    (214906, 2613),
    (214906, 2614),
    (214906, 2615),
    (214907, 2613),
    (214907, 2614),
    (214907, 2615),
    (214908, 2613),
    (214908, 2614),
    (214908, 2615),
    (214000, 2613),
    (213004, 4444),
    (111111, 5555),
    (111111, 5556),
    (111112, 5556), 
    (111112, 5555)

T-SQL:

;WITH SequenceCTE AS (
    SELECT 
        *,
        COUNT(*) OVER (PARTITION BY Sequence) AS SequenceCnt
    FROM #Data
), RankCTE AS (
    SELECT 
        *,
        DENSE_RANK() OVER (PARTITION BY SequenceCnt, Sequence ORDER BY SequenceCnt, ID) AS RankNo,
        ROW_NUMBER() OVER (PARTITION BY SequenceCnt, ID ORDER BY Sequence, ID) AS RowNo
    FROM SequenceCTE 
)
SELECT Sequence, ID
FROM RankCTE
WHERE RankNo = RowNo

Вывод:

----------------
Sequence    ID
----------------
214000      2613
213004      4444
111111      5555
111112      5556
214906      2613
214907      2614
214908      2615

Обновление (особый случай с одним идентификатором в последовательности):

;WITH SequenceCTE AS (
    SELECT 
        *,
        COUNT(*) OVER (PARTITION BY Sequence) AS SequenceCnt
    FROM #Data
), RankCTE AS (
    SELECT 
        *,
        CASE 
            WHEN SequenceCnt = 1 THEN 1
            ELSE DENSE_RANK() OVER (PARTITION BY SequenceCnt, Sequence ORDER BY SequenceCnt, ID) 
        END AS RankNo,
        CASE 
            WHEN SequenceCnt = 1 THEN 1
            ELSE ROW_NUMBER() OVER (PARTITION BY SequenceCnt, ID ORDER BY Sequence, ID) 
        END AS RowNo
    FROM SequenceCTE 
)
SELECT Sequence, ID
FROM RankCTE
WHERE RankNo = RowNo
...