2013-06-08 17 views
5

Sto tentando di completare una query sql ma mi dà problemi in questo momento, potrebbe qualcuno potrebbe aiutarmi con esso.Risultati di query di raggruppamento SQL per una singola colonna

Ecco le tabelle in versione ridotta (mi dispiace per i nomi francesi):

Lessico

ID 
terme_fr 
definition_fr  

DomaineDuTerme

lexique_id 
domaine_id 

Domaine

ID 
domaine_fr 

Quindi, un elemento nel tavolo Lexique può avere molti domini e un dominio può essere utilizzato per molti elementi Lexique. Il tavolo DomaineDuTerme è lì come intermedio che contiene molte e molte relazioni.

Vorrei la mia richiesta per raggruppare domaine_fr in una singola riga del recordset per ogni elemento distinto di Lexique. Attualmente, la richiesta mi restituisce un record per ogni relazione trovata nella tabella intermedia. Ho bisogno di questa tabella intermedia per sapere in quale (i) dominio (e) un elemento di Lexique deve applicare i filtri quando necessario.

Ecco la mia richiesta finora:

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' ` 

Con questa richiesta, se l'elemento 'test' hanno associazioni multipli Domaines, mi metterò multipli record come risultati. Mi piacerebbe ottenere un singolo record in cui le associazioni dei multipli sarebbero elencate nel campo Dom.domaine_fr.

È possibile? Ho provato con DISTINCT e ORDER BY, così come con tutte le versioni di JOIN, ma ho ancora tutte le associazioni.

So che potrei farlo in query separate o in codice dopo aver ottenuto il recordset, ma sono sicuro che c'è un modo tramite SQL. Sono anche aperto a riorganizzare lo schema del database se questo può essere d'aiuto.

Grazie mille!

+2

Potete fornire i dati di esempio e risultati desiderati? Inoltre, quale RDBMS stai usando? – sgeddes

risposta

5

Se sto capendo correttamente la tua domanda, vuoi combinare tutte le righe domaine_fr in una singola riga, magari delimitata da virgole? In tal caso, la risposta corretta dipende dal RDBMS che si sta utilizzando. Per MySQL, è possibile utilizzare GROUP_CONCAT e per Oracle è possibile utilizzare LISTAGG. SQL Server lo rende un po 'più difficile, ma è possibile utilizzare FOR XML per ottenere gli stessi risultati.


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

Grazie per la risposta dettagliata, questo è esattamente ciò di cui avevo bisogno. –

+0

@Oli_G - np, felice di poterti aiutare! – sgeddes

Problemi correlati