SQL Server等同于GROUP_CONCAT()

时间:2013-10-01 07:55:37

标签: sql sql-server join string-aggregation

我有这个数据库:

enter image description here

我需要为每个客户端获取以下数据:

  • 客户名称
  • 合同名称
  • 项目(S)
  • 从当月第一天到当月最后一天记录项目时间的员工
  • 每个员工在该月记录的总小时数
  • 员工费率
  • 每位员工的总费用(即员工费率x员工工作小时数)
  • 每份合约的结算联系人[姓名,地址]

到目前为止我有以下查询,但我需要实现MySQL的GROUP_CONCAT()

的MSSQL版本
SELECT 

Cl.LegalName AS ClientNames,
Cr.ContractDesc AS ContractNames,
P.ProjectName AS ProjectNames,
( E.FirstName + ' ' + E.LastName ) AS EmployeeNames,
SUM( WH.HoursWorked ) AS TotalHours, 
( SUM( WH.HoursWorked ) * BR.Rate ) AS TotalCharges, 
( Ca.FirstName + Ca.LastName + ', ' + Ca.AddrLine1 ) AS BillingContacts

FROM Clients Cl
JOIN Contracts Cr
ON( Cl.ClientID = Cr.ClientID )

JOIN Projects P 
ON( Cr.ContractID = P.ContractID )

JOIN EmployeesProjects EP
ON( P.ProjectID = EP.ProjectID )

JOIN Employees E 
ON( EP.EmpID = E.EmpID )

JOIN WorkHours WH
ON( E.EmpID = WH.EmpID )

JOIN BillingRates BR
ON( E.TitleID = BR.TitleID ) AND ( E.Level = BR.Level )

JOIN ContractsContacts CC
ON( Cr.ContractID = CC.ContractID )
JOIN Contacts Ca
ON( CC.ContactID = Ca.ContactID )

WHERE WH_Month = 4
AND WH_Year = 2013

当我开始关注this示例时,我到达此处并停止,因为我意识到我无法从其他子查询(ProjectNames)引用表别名(Cr)。

SELECT 
Cl.LegalName AS ClientNames, 
(
    SELECT ContractDesc + ', '
    FROM Contracts Cr
    WHERE Cl.ClientID = Cr.ClientID 
    FOR XML PATH('')
) ContractNames,
(
    SELECT ProjectName + ', '
    FROM Projects P
    WHERE Cr.ContractID = P.ContractID
    FOR XML PATH('')
) ProjectNames


FROM Clients Cl

我到底该怎么做?

3 个答案:

答案 0 :(得分:1)

尝试 CROSS APPLY 执行此操作:

例如:

SELECT Cl.LegalName AS ClientNames,
B.ContractDesc AS ContractNames,
P.ProjectName AS ProjectNames,
( E.FirstName + ' ' + E.LastName ) AS EmployeeNames,
SUM( WH.HoursWorked ) AS TotalHours, 
( SUM( WH.HoursWorked ) * BR.Rate ) AS TotalCharges, 
( Ca.FirstName + Ca.LastName + ', ' + Ca.AddrLine1 ) AS BillingContacts

FROM Clients Cl
JOIN Contracts Cr ON( Cl.ClientID = Cr.ClientID )
JOIN Projects P ON( Cr.ContractID = P.ContractID )
JOIN EmployeesProjects EP ON( P.ProjectID = EP.ProjectID )
JOIN Employees E ON( EP.EmpID = E.EmpID )
JOIN WorkHours WH ON( E.EmpID = WH.EmpID )
JOIN BillingRates BR ON( E.TitleID = BR.TitleID ) AND ( E.Level = BR.Level )
JOIN ContractsContacts CC ON( Cr.ContractID = CC.ContractID )
JOIN Contacts Ca ON( CC.ContactID = Ca.ContactID ) 
CROSS APPLY (
    SELECT Cr1.ContractDesc + ', '
    FROM Contracts Cr1
    WHERE Cl.ClientID = Cr1.ClientID 
    FOR XML PATH('')
) B (ContractDesc)
WHERE WH_Month = 4 AND WH_Year = 2013

答案 1 :(得分:1)

喜欢这个

   SELECT Cl.LegalName AS ClientNames,
   ContractNames
   FROM Clients Cl
    cross apply 
   (SELECT Cr1.ContractDesc + ', '
    FROM Contracts Cr1
      WHERE Cl.ClientID = Cr1.ClientID  For XML PATH(''))a1 (ContractNames)

答案 2 :(得分:0)

STRING_AGG几乎相当于MySQL中的GROUP_CONCAT。请参阅Microsoft here

的官方文档

请注意,STRING_AGG不允许使用文本类型,因此如果要在文本字段上连接,则需要转换为NVARCHAR。

示例:

STRING_AGG(CONVERT(NVARCHAR(2000), your_text_field_name), ',')