Sql 将分组的列分组而不使用子查询
我认为用一个例子可以更容易地解释这一点,所以假设我们有这样一个数据库:Sql 将分组的列分组而不使用子查询,sql,sql-server,Sql,Sql Server,我认为用一个例子可以更容易地解释这一点,所以假设我们有这样一个数据库: +-----------------+------------+-----------------+ | InterventionId | Doctors | Tools | +-----------------+------------+-----------------+ | 1 | Tom, John | Scalpel, Hammer | |
+-----------------+------------+-----------------+
| InterventionId | Doctors | Tools |
+-----------------+------------+-----------------+
| 1 | Tom, John | Scalpel, Hammer |
| 2 | Tom, Homer | Hammer, Bulb |
+-----------------+------------+-----------------+
- 第一个表是
,它存储Id及其任何内容 需要干预
- 第二个是医生
- 第三个是
工具
- 第四个是一个N-N表,它将每个干预与所有干预匹配
医生,我们称之为
doctorsonintervention
- 第五个是另一个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 |
+-----------------+------------+
但我们需要添加另一个专栏,就像医生一样,但使用干预中使用的工具,比如:
+-----------------+------------+-----------------+
| InterventionId | Doctors | Tools |
+-----------------+------------+-----------------+
| 1 | Tom, John | Scalpel, Hammer |
| 2 | Tom, Homer | Hammer, Bulb |
+-----------------+------------+-----------------+
将以前的代码包装到子查询中,然后根据创建另一个
分组是很容易的,但我想知道是否有更正确的方法来创建此分组,因为我的数据库表有几十列。您可以使用string\u agg()
。我建议使用子查询<代码>应用
可用于:
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
字符串连接方法。我认为您需要另一个表来关联
表干预措施
+-----------------+------------+
| InterventionId | Doctors |
+-----------------+------------+
| 1 | Tom, John |
| 2 | Tom, Homer |
+-----------------+------------+
工作台工具
+-----------------+----------------+
| InterventionId | Doctors |
+-----------------+----------------+
| 1 | Scalpel, Hammer|
| 2 | Hammer, Bulb |
+-----------------+----------------+
表格干预工具(新增)
查询将被删除
SELECT InterventionId, STRING(Doctors.Name, ', ')
FROM Interventions I WITH (NOLOCK)
INNER JOIN Doctors D WITH (NOLOCK) ON D.Id = I.DoctorId
INNER JOIN Interventions_tool IT WITH (NOLOCK) ON I.Id = IT.ToolId
GROUP BY I.Id, D.Id;
+-----------------+------------+-----------------+
| InterventionId | Doctors | Tools |
+-----------------+------------+-----------------+
| 1 | Tom, John | Scalpel, Hammer |
| 2 | Tom, Homer | Hammer, Bulb |
+-----------------+------------+-----------------+
什么是
STRING()
函数?这不是有效的t-sql。我不知道有哪个版本的sql函数是字符串。一些表定义、样本数据和一些对查询有效的东西怎么样?表和工具之间存在什么样的关系?只有在两个表之间至少有一列时,才能创建相关表them@GordonLinoff修好了是的,我写的,我叫它ToolsOnInterventios@CarlosL奥佩兹马里我不明白?你使用了这个建议吗?如果你按这3个分组,你会得到每个医生使用的所有工具组合,这不是我需要的。
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;