Странная группировка SQL - Соответствие строк с общими значениями для любого из двух столбцов? - PullRequest
0 голосов
/ 07 января 2019

Я пытаюсь использовать рекурсивный CTE, чтобы добавить столбец идентификатора группы к моим данным для целей сопоставления. Я использую код здесь ( Сценарий странной группировки SQL Server по нескольким столбцам и ИЛИ ), но вывод этого кода не работает должным образом.

У меня есть таблица SQL Server #cache_resale_tbl, и я хотел бы добавить столбец идентификатора группы, который объединяет строки в группы.

Название таблицы: #cache_resale_tbl

Столбцы: идентификатор ключа, номер заказа на покупку ("col1"), номер билета ("col2")

Я хочу добавить столбец с идентификатором группы, и все строки с одинаковым номером заказа или номером билета получат одинаковый идентификатор группы.

Вот код, который я использую:

with g (rootid, previd, level, KeyID, col1, col2) as 
(
    select 
        KeyID, 0, 1, KeyID, col1, col2 
    from 
        #cache_resale_tbl

    union all

    select 
        g.rootid, g.KeyID, g.level + 1, v.KeyID, v.col1, v.col2
    from 
        g
    join 
        #cache_resale_tbl v on v.col1 = g.col1 or v.col2 = g.col2
    where 
        v.KeyID > g.KeyID
),
m (KeyID, rootid) as 
(
    select 
        KeyID, min(rootid) 
    from 
        g 
    group by 
        KeyID
)
select 
    v.KeyID, v.col1, v.col2,
    cast(min(rootid) as varchar(50)) as 'Group ID' 
from 
    m
inner join 
    #cache_resale_tbl v on v.KeyID = m.KeyID
group by 
    v.KeyID, v.col1, v.col2;

Пример ввода для #cache_resale_tbl:

KeyID   col1   col2
-----------------------
1   PO25303309  255207
2   PO25303304  257459
3   PO25303305  257459
4   PO25303306  257459
5   PO25303307  257459
6   PO25303309  257459

Вывод кода:

KeyID   col1   col2    Group ID
----------------------------
1   PO25303309  255207  1
2   PO25303304  257459  2
3   PO25303305  257459  2
4   PO25303306  257459  2
5   PO25303307  257459  2
6   PO25303309  257459  1

Желаемый вывод:

KeyID   col1   col2    Group ID
----------------------------
1   PO25303309  255207  1
2   PO25303304  257459  1
3   PO25303305  257459  1
4   PO25303306  257459  1
5   PO25303307  257459  1
6   PO25303309  257459  1

Мой ожидаемый вывод - столбец идентификатора группы возвращает одинаковое число для этих строк. Все последние 5 строк должны иметь одинаковый идентификатор группы, поскольку они имеют одинаковое значение col2. И первая заявка также принадлежит этой группе, потому что строки 1 и 6 имеют одинаковое значение col1. Любая строка с одинаковым значением col1 или col2 должна находиться в одном и том же идентификаторе группы. Поэтому, мой желаемый вывод - сопоставить их все в одну группу, которую код, который я использую, похоже, не делает.

Любая помощь по этому вопросу будет принята с благодарностью :) Спасибо!

1 Ответ

0 голосов
/ 08 января 2019

Я полагаю, что это делает то, что первоначально было задано в вопросе, с одной оговоркой. Заказы, которые не повторяются ни в столбце col1, ни в столбце col2, группируются вместе (например, строка комментария union all select 8, 'PO25303311', 331503 в CTE).

;with cache_resale_tbl as(
select
 1 KeyID,  'PO25303309' col1, 255207 col2
union all select 2,   'PO25303304',  257459
union all select 3,   'PO25303305',  257459
union all select 4,   'PO25303306',  257459
union all select 5,   'PO25303307',  257459
union all select 6,   'PO25303309',  257459
union all select 7,   'PO25303310',  331502
--union all select 8,   'PO25303311',  331503
)


,CountRepeatVal AS(
select 
    cache_resale_tbl.*
    ,CntCol1                = COUNT(*) over (partition by col1)
    ,CntCol2                = COUNT(*) over (partition by col2)

from cache_resale_tbl

)

,Grouped AS(
select 
    CountRepeatVal.*
    ,Groups                 = case when (CountRepeatVal.CntCol1 > 1 OR CountRepeatVal.CntCol2 > 1) then 0 else 1 end

from CountRepeatVal
)

select 
    --Grouped.*
    Grouped.KeyID
    ,Grouped.col1
    ,Grouped.col2
    ,GROUP_ID       = DENSE_RANK() OVER(ORDER BY Groups)

FROM Grouped

Вот дБ <> скрипка

...