Ich habe zufällig ähnliche Aufgabe haben. Die Daten, mit denen ich arbeite, sind etwas größer, daher musste ich einen effektiven Ansatz finden. Grundsätzlich habe ich 2 Arbeitsansätze gefunden.
Eins ist reines SQL - hier ist eine Kernabfrage. Im Grunde gibt es Ihnen die kleinste ParentID mit derselben Sammlung von Kindern, die Sie dann als Gruppen-ID verwenden können (Sie können sie auch mit row_number
aufzählen). Als kleine Anmerkung - ich benutze cte hier, aber in der realen Welt würde ich vorschlagen, gruppierte Eltern in temporäre Tabelle zu setzen und Indizes auf dem Tisch auch hinzuzufügen.
;with cte_parents as (
-- You can also use different statistics to narrow the search
select
[ParentID],
count(*) as cnt,
min([Type]) as min_Type,
max([Type]) as max_Type
from Table1
group by
[ParentID]
)
select
h1.ParentID,
k.ParentID as GroupID
from cte_parents as h1
outer apply (
select top 1
h2.[ParentID]
from cte_parents as h2
where
h2.cnt = h1.cnt and
h2.min_Type = h1.min_Type and
h2.max_Type = h1.max_Type and
not exists (
select *
from (select tt.[Type] from Table1 as tt where tt.[ParentID] = h2.[ParentID]) as tt1
full join (select tt.[Type] from Table1 as tt where tt.[ParentID] = h1.[ParentID]) as tt2 on
tt2.[Type] = tt1.[Type]
where
tt1.[Type] is null or tt2.[Type] is null
)
order by
h2.[ParentID]
) as k
ParentID GroupID
----------- --------------
1 1
2 2
3 1
4 2
Eine andere ist ein bisschen schwieriger und Sie müssen vorsichtig sein, wenn Sie es verwenden. Aber überraschenderweise funktioniert es nicht so schlecht. Die Idee besteht darin, Kinder zu einer großen Zeichenfolge zu verketten und dann nach diesen Zeichenfolgen zu gruppieren. Sie können jede verfügbare Verkettungsmethode verwenden (xml trick oder clr, wenn Sie SQL Server 2017 haben). Der wichtige Teil ist, dass Sie eine geordnete Verkettung verwenden müssen, so dass jede Zeichenkette Ihre Gruppe genau repräsentiert. Ich habe dafür eine spezielle CLR-Funktion (dbo.f_ConcatAsc
) erstellt.
;with cte1 as (
select
ParentID,
dbo.f_ConcatAsc([Type], ',') as group_data
from Table1
group by
ParentID
), cte2 as (
select
dbo.f_ConcatAsc(ParentID, ',') as parent_data,
group_data,
row_number() over(order by group_data) as rn
from cte1
group by
group_data
)
select
cast(p.value as int) as ParentID,
c.rn as GroupID,
c.group_data
from cte2 as c
cross apply string_split(c.parent_data, ',') as p
ParentID GroupID group_data
----------- -------------------- --------------------------------------------------
2 1 ChildTypeA,ChildTypeB,ChildTypeC
4 1 ChildTypeA,ChildTypeB,ChildTypeC
1 2 ChildTypeA,ChildTypeB,ChildTypeC,ChildTypeD
3 2 ChildTypeA,ChildTypeB,ChildTypeC,ChildTypeD
Ich bekomme immer noch nicht, wie Sie asisgn configgroup – TheGameiswar
Könnten Sie ein wenig mehr auf Ihrem "endlichen Satz" von Konfigurationen erweitern? Sprechen wir von 1-10 Konfigurationen oder 1k-100k Konfigurationen? Eine SQL-Geige mit repräsentativen Daten ist willkommen. –