SQL Server equivalent to GROUP_CONCAT() [duplicate]

孤街醉人 提交于 2019-12-10 17:18:36

问题


I have this database:

And I need to get the following data for each Client:

  • Client Name
  • Contract Name(s)
  • Project(s)
  • Employees who logged hours to a project from the first day of the current month until the last day of the current month
  • Total number of hours logged for each employee during the month
  • Employee rate
  • Total Charges per employee (i.e. employee rate x employee hours worked)
  • Billing contact(s) [name, address] for each contract

I have the following query so far, but I need to implement a MSSQL version of MySQL's GROUP_CONCAT( )

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

When I started following this example, I got to here and stopped because I realized that I couldn't reference table aliases (Cr) from other subqueries (ProjectNames).

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

How exactly do I go about doing this?


回答1:


Try CROSS APPLY to do yhis:

For Example:

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



回答2:


do like this

   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)



回答3:


STRING_AGG is almost equivalent to GROUP_CONCAT in MySQL. Refer the official document from Microsoft here

Note that STRING_AGG doesn't allow Text type, so you need to convert to NVARCHAR if you will concatenate on a Text field.

Example:

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


来源:https://stackoverflow.com/questions/19110850/sql-server-equivalent-to-group-concat

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!