针对单个列的SQL分组查询结果

6

我想完成一条SQL查询,但目前遇到了问题,希望有人能帮助我。

以下是表的简化版本(对于法语名称我很抱歉):

词典

ID  
terme_fr  
definition_fr    

DomaineDuTerme

lexique_id  
domaine_id  

领域

ID  
domaine_fr

因此,Lexique表中的一个元素可以有多个Domaine,而一个Domaine可以用于多个Lexique元素。DomaineDuTerme表作为一个中间表,包含这些多对多关系。
我希望我的查询将每个不同的Lexique元素的domaine_fr分组到记录集的单个行中。目前,该请求返回中间表中找到的每个关系的记录。当需要应用过滤器时,我需要这个中间表知道Lexique元素适用于哪些Domaine。
以下是我目前的请求:
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”元素具有多个域关联,则将获得多个记录作为结果。我希望能够获得一个单独的记录,其中多个关联将在Dom.domaine_fr字段中列出。
这种情况是否可能?我尝试使用DISTINCT和ORDER BY,以及每个版本的JOIN,但仍然获得所有关联。
我知道我可以在单独的查询或在获取记录集后的代码中完成它,但我相信有一种通过SQL的方法。我也愿意重新组织数据库模式,如果这有助于解决问题。
非常感谢!

2
你能提供样本数据和期望的结果吗?另外,你使用的是哪个关系型数据库管理系统? - sgeddes
1个回答

7
如果我理解你的问题正确,你想将所有domaine_fr行合并成一行,可能以逗号分隔?如果是这样,正确的答案取决于你所使用的关系数据库管理系统。对于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

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

@Oli_G -- 没问题,很高兴能帮到你! - sgeddes

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接