Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/79.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 将分组的列分组而不使用子查询_Sql_Sql Server - Fatal编程技术网

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;