2013-08-26 24 views
5

Ho un problema durante la creazione di un'istruzione SQL per sqlserver2008. Ho i seguenti dati:Istruzione SQL per due colonne di gruppo

city  person  priority 
----------------------------------- 
Linz  Mike  1 
Wien  Mike  1 
Linz  Tom  1 
Wien  Tom  1 
Linz  John  1 
Linz  Sarah  2 

Ciò significa che le persone Mike e Tom scelgono le città Linz e Wien con priorità 1.
John sceglie Linz con priorità 1.
Sarah sceglie Linz con priorità 2.

ora voglio il seguente output:

cities   persons   priority 
----------------------------------- 
Linz, Wien  Mike, Tom  1 
Linz   John   1 
Linz   Sarah   2 

ho già seguito SQL-affermazione, ma non ottengo il risultato atteso da questa query direbbe che John ha anche una voce per Wien con priorità 1.

SELECT 
(SELECT 
    STUFF((SELECT ', ' + d.City 
    FROM (SELECT DISTINCT d2.City FROM dbo.DummyTable d2 
     WHERE d2.Priority = d1.Priority) d 
    FOR XML PATH('')), 1, 2, '') 
) 
AS Cities, 
(SELECT 
    STUFF((SELECT ', ' + d.Person 
    FROM (SELECT DISTINCT d2.Person FROM dbo.DummyTable d2 
     WHERE d2.Priority = d1.Priority) d 
    FOR XML PATH('')), 1, 2, '') 
) 
AS Persons, 
d1.Priority 
FROM 
dbo.DummyTable d1 
GROUP BY d1.Priority 

È anche possibile utilizzare questo SQL Fiddle

Qualche idea su come questa query possa essere scritta in SQL?

risposta

4

Ecco un modo per farlo:

;with PersonCityGroupPreferences as (
    select 
    Person, 
    Priority, 
    stuff ((
     select ', ' + d2.City 
     from DummyTable d2 
     where d1.Priority = d2.Priority 
      and d1.Person = d2.Person 
     FOR XML PATH('') 
    ), 1, 2, '') Cities 
    from DummyTable d1 
    group by Person, Priority 
) 
select 
    Cities, 
    stuff ((
    select ', ' + p2.Person 
    from PersonCityGroupPreferences p2 
    where p1.Cities = p2.Cities 
     and p1.Priority = p2.Priority 
    FOR XML PATH('') 
), 1, 2, '') Persons, 
    Priority 
from PersonCityGroupPreferences p1 
group by Priority, Cities 

collegamento SQLFiddle: http://www.sqlfiddle.com/#!3/d831d/57

Al fine di raggiungere la finale risultato, ho diviso la soluzione in due passaggi:

  1. Ottenere un set di risultati che raggruppa i dati per Person e Priority e contiene l'elenco separato da virgole delle città come una terza colonna

  2. Prendere il set di risultati ottenuto un punto 1 e fare la stessa cosa, ma la società Gruppo dalle colonne Cities (l'elenco separato da virgola) e Priority e produrre un elenco separato da virgole di persone corrispondenti.

Nella query precedente, il passo 1 è questa query:

select 
    Person, 
    Priority, 
    stuff ((
    select ', ' + d2.City 
    from DummyTable d2 
    where d1.Priority = d2.Priority 
    and d1.Person = d2.Person 
    FOR XML PATH('') 
), 1, 2, '') Cities 
from DummyTable d1 
group by Person, Priority 

Ecco come i risultati parziali appaiono in SQL: http://www.sqlfiddle.com/#!3/d831d/58

Ho poi esposto la prima query come CTE, rendendo è disponibile per la query (esterna) 2, che essenzialmente fa la stessa cosa, ma con criteri di raggruppamento diversi.

0

Penso che si possa raggiungere questo obiettivo al massimo: http://www.sqlfiddle.com/#!3/d831d/26

SELECT 
(SELECT 
    STUFF((SELECT ', ' + d.City 
    FROM (SELECT DISTINCT d2.City FROM dbo.DummyTable d2 
     WHERE d2.Priority = d1.Priority and d2.City = d1.City) d 
    FOR XML PATH('')), 1, 2, '') 
) 
AS Cities, 
(SELECT 
    STUFF((SELECT ', ' + d.Person 
    FROM (SELECT DISTINCT d2.Person FROM dbo.DummyTable d2 
     WHERE d2.Priority = d1.Priority and d2.City = d1.City) d 
    FOR XML PATH('')), 1, 2, '') 
) 
AS Person, 
d1.Priority 
FROM 
dbo.DummyTable d1 
GROUP BY d1.Priority,d1.City