Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/26.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 server 如何在按1列分组的联接表中对多行多列进行分组_Sql Server_Group By_For Xml Path - Fatal编程技术网

Sql server 如何在按1列分组的联接表中对多行多列进行分组

Sql server 如何在按1列分组的联接表中对多行多列进行分组,sql-server,group-by,for-xml-path,Sql Server,Group By,For Xml Path,我有一张三张不同桌子的联合桌,像这样 Select DoctorTable.Doctor, NurseTable.Nurse , PatientTable.Patents FROM PatientTable LEFT JOIN DoctorTable on DoctorTable.DoctorCode = PatientTable.DoctorCode LEFT JOIN NurseTable on DoctorTable.DoctorCode = NurseTable.DoctorCo

我有一张三张不同桌子的联合桌,像这样

Select DoctorTable.Doctor, NurseTable.Nurse , PatientTable.Patents 

FROM PatientTable

LEFT JOIN DoctorTable on DoctorTable.DoctorCode = PatientTable.DoctorCode

LEFT JOIN NurseTable on DoctorTable.DoctorCode = NurseTable.DoctorCode


Patient     Doctor        Nurse
John        Peter         Mary
John        Peter         Amy
Kate        Terry         Mary
Kate        Leo           Ivy
Paul        NULL          NULL
Emily       NULL          NULL
我想在“医生”列中用逗号连接具有相同值的行,得到下面的结果

Patient     Doctor        Nurse
John        Peter         Mary, Amy
Kate        Terry, Leo    Mary, Ivy
Paul        Null          Null
Emily       NULL          NULL

由于我还有一些列要与这个表连接,并且还需要用“,”对行进行分组,因此使用FOR XML PATH(“”)对每个列进行分组将非常缓慢。那么我如何才能有效地对这个表进行分组呢?

我认为答案是使用一个聚合函数来连接组中的行。太糟糕了,TSQL没有一个聚合连接函数(这有多困难?),但是如果您不介意使用SQLCLR,下面介绍如何在MSDN中使用.NET创建用户定义的聚合连接函数:

<Serializable(), Microsoft.SqlServer.Server.SqlUserDefinedAggregate(Microsoft.SqlServer.Server.Format.UserDefined, IsInvariantToNulls:=True, IsInvariantToDuplicates:=False, IsInvariantToOrder:=False, MaxByteSize:=8000)> _
Public Class Concatenate : Implements Microsoft.SqlServer.Server.IBinarySerialize

    Private Builder As StringBuilder

    Public Sub Init()
        Builder = New StringBuilder
    End Sub

    Public Sub Accumulate(ByVal value As SqlString)
        If value.IsNull Then Return
        Builder.Append(",").Append(value.Value)
    End Sub

    Public Sub Merge(ByVal other As Concatenate)
        Builder.Append(other.Builder)
    End Sub

    Public Function Terminate() As SqlString
        If Builder Is Nothing Then Return New SqlString("")
        Return New SqlString(Builder.ToString.Substring(1))
    End Function

    Public Sub Read(ByVal r As BinaryReader) Implements Microsoft.SqlServer.Server.IBinarySerialize.Read
        If r Is Nothing Then Throw New ArgumentNullException("r")
        Builder = New StringBuilder(r.ReadString())
    End Sub

    Public Sub Write(ByVal w As BinaryWriter) Implements Microsoft.SqlServer.Server.IBinarySerialize.Write
        If w Is Nothing Then Throw New ArgumentNullException("w")
        w.Write(Builder.ToString())
    End Sub

End Class
SELECT PatientCode, Patient, dbo.Concatenate(Doctor), dbo.Concatenate(Nurse) 
FROM PatientTable
LEFT JOIN DoctorTable on DoctorTable.DoctorCode = PatientTable.DoctorCode
LEFT JOIN NurseTable on DoctorTable.DoctorCode = NurseTable.DoctorCode
GROUP BY PatientCode, Patient