I'm trying to complete a sql query but it gives me trouble right now, maybee someone could help me with it.
Here's the tables in shorter version (sorry for the french names):
Lexique
ID
terme_fr
definition_fr
DomaineDuTerme
lexique_id
domaine_id
Domaine
ID
domaine_fr
So, one element in the Lexique table can have many Domaine, and one Domaine can be used for many Lexique element. The DomaineDuTerme table is there as an intermediate that contains thoses many to many relationships.
I would like my query to regroup domaine_fr in a single row of the recordset for each distinct Lexique element. Presently, the request returns me a record for every relationship found in the intermediate table. I need this intermediate table to know in wich Domaine(s) a Lexique element is to apply filters when needed.
Here is my request so far:
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' `
With this request, if the 'test' element have multiples Domaines associations, I will get multiples records as results. I would like to get a single record where the multiples associations would be listed in the Dom.domaine_fr field.
Is this possible? I did try with DISTINCT and ORDER BY, as well as with every versions of JOIN but I still get all associations.
I know I could do it in separate queries, or in code after getting the recordset, but I'm sure there is a way via SQL. I'm also open to reorganise the database schema if this can helps.
Many Thanks !
If I'm understanding your question correctly, you want to combine all the domaine_fr rows into a single row, perhaps comma delimited? If so, the correct answer depends on the RDBMS that you are using. For MySQL, you could use GROUP_CONCAT
and for Oracle you could use LISTAGG
. SQL Server makes it a little more difficult, but you could use FOR XML
to achieve the same results.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With