对分组的列进行分组而无需子查询

时间:2019-02-26 16:05:54

标签: sql sql-server

我认为这可以通过示例更容易解释,所以我们说我们有一个这样的数据库:

  • 第一个表是Interventions,其中存储了ID及其所有内容 需求。
  • 第二个是Doctors
  • 第三个是Tools
  • 第四个是N-N表,它将每个干预与它的所有匹配 医生,我们称它为DoctorsOnInterventions
  • 第五个是另一个N-N表,它与每次干预所使用的每个工具匹配,我们将其称为ToolsOnInterventions

好,现在我们可以做到:

SELECT InterventionId, STRING_AGG(Doctors.Name, ', ')
FROM Interventions
INNER JOIN Doctors ON Doctors.Id = DoctorsOnInterventions.DoctorId
GROUP BY Intervention.Id, Doctors.Id;

并获得:

+-----------------+------------+
| InterventionId  |  Doctors   |
+-----------------+------------+
|               1 | Tom, John  |
|               2 | Tom, Homer |
+-----------------+------------+

但是我们需要像Doctors一样添加另一列,但要使用该干预中使用的工具,如下所示:

+-----------------+------------+-----------------+
| InterventionId  |  Doctors   |      Tools      |
+-----------------+------------+-----------------+
|               1 | Tom, John  | Scalpel, Hammer |
|               2 | Tom, Homer | Hammer, Bulb    |
+-----------------+------------+-----------------+

将先前的代码包装在子查询上然后进行另一个group by很容易,但是我想知道是否有更正确的方法来实现此目的,因为我的数据库表有几十个列

3 个答案:

答案 0 :(得分:0)

您可以使用string_agg()。我会建议子查询;可以使用apply

SELECT i.*, d.doctors, t.tools
FROM Interventions i OUTER APPLY
     (SELECT STRING_AGG(d.name, ',') as doctors
      FROM DoctorsOnInterventions doi JOIN
           Doctors d
           ON d.Id = doi.DoctorId
      WHERE doi.interventionId = i.id
     ) d OUTER APPLY
     (SELECT STRING_AGG(t.name, ',') as tools
      FROM ToolsOnInterventions toi JOIN
           Tools t
           ON t.id = toi.ToolId
      WHERE toi.interventionId = i.id
     ) t ;

在旧版SQL Server中,您可以使用字符串串联的FOR XML PATH方法。

答案 1 :(得分:0)

我想您那时需要另一个表。

餐桌干预

GroupByAdjacent

表格工具

+-----------------+------------+
| InterventionId  |  Doctors   |
+-----------------+------------+
|               1 | Tom, John  |
|               2 | Tom, Homer |
+-----------------+------------+

表格Interventions_tool(

+-----------------+----------------+
| InterventionId  |  Doctors       |
+-----------------+----------------+
|               1 | Scalpel, Hammer|
|               2 | Hammer, Bulb   |
+-----------------+----------------+

查询将

+-----------------+------------+
| InterventionId  |  ToolId    |
+-----------------+------------+
|               1 | 1          |
|               2 | 2          |
+-----------------+------------+

答案 2 :(得分:0)

SELECT InterventionId, STRING(Doctors.Name, ', '),STRING(Tools.name,',')
FROM Interventions
INNER JOIN Doctors ON Doctors.Id = DoctorsOnInterventions.DoctorId 
INNER JOIN Tools on tools.id = ToolsOnInterventions.toolsid
GROUP BY Intervention.Id, Doctors.Id, tools.id;