我正在尝试完成一个SQL查询,但它现在给我带来了麻烦,也许有人可以帮助我。
以下是较短版本的表格(对不起法语名称):
Lexique
ID
terme_fr
definition_fr
DomaineDuTerme
lexique_id
domaine_id
Domaine
ID
domaine_fr
因此,Lexique表中的一个元素可以有许多Domaine,一个Domaine可以用于许多Lexique元素。 DomaineDuTerme表是一个包含多对多关系的中间体。
我希望我的查询在每个不同的Lexique元素的记录集的单行中重新组合domaine_fr。目前,请求返回中间表中找到的每个关系的记录。我需要这个中间表来了解Doique,一个Lexique元素是在需要时应用过滤器。
到目前为止,这是我的要求:
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' `
有了这个请求,如果'test'元素有多个Domaines关联,我会得到倍数记录作为结果。我想获得一个记录,其中多个关联将列在Dom.domaine_fr字段中。
这可能吗?我确实尝试过DISTINCT和ORDER BY,以及每个版本的JOIN,但我仍然得到所有关联。
我知道我可以在单独的查询中或在获取记录集后的代码中执行此操作,但我确信通过SQL有一种方法。我也愿意重新组织数据库模式,如果这有帮助的话。
非常感谢!
答案 0 :(得分:5)
如果我正确理解你的问题,你想将所有domaine_fr行组合成一行,也许用逗号分隔?如果是这样,正确答案取决于您使用的RDBMS。对于MySQL,您可以使用GROUP_CONCAT
,对于Oracle,您可以使用LISTAGG
。 SQL Server使其变得更加困难,但您可以使用FOR XML
来获得相同的结果。
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
甲骨文:
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