Instruction SQL pour deux colonnes de groupe

J'ai un problème pour créer une instruction SQL pour sqlserver2008. J'ai datatables suivantes:

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

Cela signifie que les personnes Mike et Tom choisissent les villes Linz et Wien avec la priorité 1.
John choisit Linz avec la priorité 1.
Sarah choisit Linz avec la priorité 2.

maintenant je veux la sortie suivante:

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

J'ai déjà SQL-Statement suivant mais je n'obtiens pas le résultat attendu car cette requête indiquerait que John a aussi une input pour Wien avec la 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 

Vous pouvez également utiliser ce violon SQL

Des idées comment cette requête pourrait être écrite en SQL?

Voici un moyen de le faire:

 ;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 

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

Afin d'atteindre le résultat final, j'ai divisé la solution en deux étapes:

  1. Obtenir un jeu de résultats qui regroupe datatables par Person et par Priority et contient la list des villes séparées par des virgules en tant que troisième colonne

  2. Prenez l'set de résultats obtenu un point 1 et faites la même chose, mais maintenant groupez par les colonnes Cities (la list séparée par des virgules) et Priority et produisez une list de personnes séparées par des virgules.

Dans la requête ci-dessus, l'étape 1 est cette requête:

 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 

Voici comment les résultats partiels apparaissent dans SQL: http://www.sqlfiddle.com/#!3/d831d/58

J'ai ensuite exposé la première requête en tant que CTE , la rendant accessible à la requête (externe) 2, qui fait essentiellement la même chose, mais avec des critères de regroupement différents.

Je pense que vous pouvez atteindre cet objective au maximum: 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