Реляционное деление: найти каждый уникальный набор "дочерних" значений в столбце

После долгих поисков, кажется, наиболее relational division проблемы целевых групп с соответствующими членами. Возможно, у меня проблемы с ключевыми словами, но я хочу что-то немного другое: учитывая родителей / группу и набор детей / участников, как мне найти каждую уникальную комбинацию членов, независимо от родителя?

Используя следующий пример источника

CREATE TABLE #m (Parent char(1), ChildID int)

INSERT INTO #m
VALUES ('a',1), ('a', 2), ('a',4),
       ('b',1), ('b', 3), ('b',4),
       ('c',1), ('c', 4), ('c',2),
       ('d',1), ('d',4),
       ('e',3), ('e', 1),
       ('f',4),
       ('g',3), ('g', 4), ('g',1);

SELECT * FROM #m

Я бы искал результат, подобный (1, 2, 4), (1, 3, 4), (1, 4), (1, 3), (4), выраженный в виде новой временной таблицы (для присоединения вернуться к #mтак, чтобы каждый Parent можно указать на его "хэш", а не на его соответствие Parent)

Есть много вариантов синтаксиса в этом материале; этот вид имеет самое большое значение для меня, но не получил ответа. Извинения за дублирование я не могу найти.

РЕДАКТИРОВАТЬ: желаемый результат, выраженный в виде набора результатов SQL:

UParent ChildID
------- -----------
u1      1
u1      2
u1      4
u2      1
u2      3
u2      4
u3      1
u3      4
u4      1
u4      3
u5      4

3 ответа

Решение

Понятно, вам нужны "уникальные" комбинации детей независимо от порядка.

Следующее получает родителей, которые эквивалентны:

select m1.Parent as Parent1, m2.Parent as Parent2
from (select m.*, count(*) over (partition by Parent) as NumKids
      from #m m
     ) m1 join
     (select m.*, count(*) over (partition by Parent) as NumKids
      from #m m
     ) m2
     on m1.ChildID = m2.ChildID
group by m1.Parent, m2.Parent
having count(*) = max(m1.NumKids) and max(m1.NumKids) = max(m2.NumKids);

Теперь мы можем получить то, что вы хотите, используя это

with parents as (
    select m1.Parent as Parent1, m2.Parent as Parent2
    from (select m.*, count(*) over (partition by Parent) as NumKids
          from #m m
         ) m1 join
         (select m.*, count(*) over (partition by Parent) as NumKids
          from #m m
         ) m2
         on m1.ChildID = m2.ChildID
    group by m1.Parent, m2.Parent
    having count(*) = max(m1.NumKids) and max(m1.NumKids) = max(m2.NumKids)
)
select distinct m.*
from (select min(Parent2) as theParent
      from parents
      group by Parent1
     ) p join
     #m m
     on p.theParent = m.Parent;

Если вы хотите новый идентификатор вместо старого, используйте:

select dense_rank() over (partition by m.Parent) as NewId, m.ChildID

в select,

Это использует for xml создать отсортированный список дочерних идентификаторов, который используется в качестве предложения раздела функции rank().

select M.Parent,
       M.ChildID
from (
     select M1.Parent,
            M1.ChildID,
            rank() over(partition by (
                                     select cast(ChildID as varchar(11))+','
                                     from #m as M2
                                     where M1.Parent = M2.Parent
                                     order by M2.ChildID
                                     for xml path('')
                                     )
                        order by M1.Parent) as rn
     from #m as M1
     ) as M
where M.rn = 1;

SQL Fiddle

Поправьте меня, если я ошибаюсь в том, как хранятся ваши данные, разве это уже не в том формате, в каком вы хотите их видеть.

Я пробовал этот запрос на основе данных вашего примера, и он выдает ожидаемый набор результатов. посмотри здесь

SELECT 'u' + CAST(DENSE_RANK() OVER (ORDER BY Parent) AS VARCHAR(10)) AS UParent
      ,ChildID
FROM #m

Набор результатов

╔═════════╦═════════╗
║ UParent ║ ChildID ║
╠═════════╬═════════╣
║ u1      ║       1 ║
║ u1      ║       2 ║
║ u1      ║       4 ║
║ u2      ║       1 ║
║ u2      ║       3 ║
║ u2      ║       4 ║
║ u3      ║       1 ║
║ u3      ║       4 ║
║ u3      ║       2 ║
║ u4      ║       1 ║
║ u4      ║       4 ║
║ u5      ║       3 ║
║ u5      ║       1 ║
║ u6      ║       4 ║
║ u7      ║       3 ║
║ u7      ║       4 ║
║ u7      ║       1 ║
╚═════════╩═════════╝
Другие вопросы по тегам