2013-06-08 20 views
5

Próbuję ukończyć kwerendę sql, ale teraz sprawia mi to kłopot, niech ktoś może mi w tym pomóc.Wyniki kwerendy grupowania SQL dla pojedynczej kolumny

Oto tabele w krótszej wersji (przepraszam za francuskimi nazwami):

Lexique

ID 
terme_fr 
definition_fr  

DomaineDuTerme

lexique_id 
domaine_id 

Domaine

ID 
domaine_fr 

Tak więc jeden element w tabeli Lexique może mieć wiele Domaine, a jedna Domaine może być użyta dla wielu elementów Lexique. Tabela DomaineDuTerme istnieje jako produkt pośredni zawierający wiele lub wiele relacji.

Chciałbym, aby moje zapytanie przegrupowało domaine_fr w jednym wierszu zestawu rekordów dla każdego odrębnego elementu Lexique. Obecnie żądanie zwraca mi rekord dla każdej relacji znalezionej w tabeli pośredniej. Potrzebuję tego pośredniego stołu, aby wiedzieć, w Domaine (s) element Lexique jest zastosowanie filtrów w razie potrzeby.

Oto moja prośba do tej pory:

SELECT 
    Lex.terme_fr, 
    Lex.definition_fr, 
    Dom.domaine_fr 
FROM 
    ((Lexique AS Lex 
    LEFT JOIN 
    DomaineDuTerme AS Ddt ON Lex.ID = Ddt.lexique_id) 
    LEFT JOIN  
    Domaine AS Dom ON Ddt.domaine_id = Dom.ID)  
WHERE Lex.terme_fr='test' ` 

Z tego wniosek, jeśli „test” elementem mieć wielokrotności Domaines stowarzyszenia, będę się wielokrotności rekordy jak wyniki. Chciałbym uzyskać pojedynczy rekord, w którym skojarzenia wielokrotności będą wymienione w polu Dom.domaine_fr.

Czy to możliwe? Próbowałem z DISTINCT i ORDER BY, a także z każdą wersją JOIN, ale nadal otrzymuję wszystkie skojarzenia.

Wiem, że mogłem to zrobić w oddzielnych zapytaniach lub w kodzie po uzyskaniu zestawu rekordów, ale jestem pewien, że istnieje sposób przez SQL. Jestem również otwarty na reorganizację schematu bazy danych, jeśli może to pomóc.

Wielkie dzięki!

+2

możesz podać przykładowe dane i oczekiwane rezultaty? Ponadto, którego RDBMS używasz? – sgeddes

Odpowiedz

5

Jeśli dobrze rozumiem Twoje pytanie, chcesz połączyć wszystkie wiersze domaine_fr w jeden wiersz, być może rozdzielany przecinkami? Jeśli tak, poprawna odpowiedź zależy od używanego RDBMS. Dla MySQL możesz użyć GROUP_CONCAT, a dla Oracle możesz użyć LISTAGG. SQL Server sprawia, że ​​jest trochę trudniejsze, ale można użyć FOR XML, aby osiągnąć takie same wyniki.


MySQL:

SELECT 
    Lex.terme_fr, 
    Lex.definition_fr, 
    GROUP_CONCAT(Dom.domaine_fr SEPARATOR ', ') AS domaine_fr 
FROM 
    ((Lexique AS Lex 
    LEFT JOIN 
    DomaineDuTerme AS Ddt ON Lex.ID = Ddt.lexique_id) 
    LEFT JOIN  
    Domaine AS Dom ON Ddt.domaine_id = Dom.ID)  
WHERE Lex.terme_fr='test' ` 
GROUP BY 
    Lex.terme_fr, 
    Lex.definition_fr 

Oracle:

SELECT 
    Lex.terme_fr, 
    Lex.definition_fr, 
    LISTAGG(Dom.domaine_fr, ',') WITHIN GROUP (ORDER BY Dom.domaine_fr) AS domaine_fr 
FROM 
    ((Lexique AS Lex 
    LEFT JOIN 
    DomaineDuTerme AS Ddt ON Lex.ID = Ddt.lexique_id) 
    LEFT JOIN  
    Domaine AS Dom ON Ddt.domaine_id = Dom.ID)  
WHERE Lex.terme_fr='test' ` 
GROUP BY 
    Lex.terme_fr, 
    Lex.definition_fr 

SQL Server:

SELECT 
    Lex.terme_fr, 
    Lex.definition_fr, 
    STUFF((SELECT ', ' + Dom2.domaine_fr 
      FROM Domaine Dom2 
      WHERE Dom.Id = Dom2.Id 
      FOR XML PATH(''), TYPE 
     ).value('.', 'NVARCHAR(MAX)'), 1, 2, '') AS domaine_fr 
FROM 
    ((Lexique AS Lex 
    LEFT JOIN 
    DomaineDuTerme AS Ddt ON Lex.ID = Ddt.lexique_id) 
    LEFT JOIN  
    Domaine AS Dom ON Ddt.domaine_id = Dom.ID)  
WHERE Lex.terme_fr='test' ` 
GROUP BY 
    Lex.terme_fr, 
    Lex.definition_fr 
+1

Dziękuję za szczegółową odpowiedź, to jest dokładnie to, czego potrzebowałem. –

+0

@Oli_G - np. Cieszę się, że mogłem pomóc! – sgeddes

Powiązane problemy