交叉应用以逗号分隔的值与GROUP BY一起返回

时间:2019-01-10 05:01:34

标签: sql-server tsql

我正在处理一个查询,以返回一个报告,该报告将每个业务部门的日志记录以及分配给每个业务部门的经理的逗号分隔列表进行分组,因此基本上有4个表。

[dbo].[Log]
[dbo].[BusinessUnit]
[dbo].[Manager]
[dbo].[BusinessUnitManager]

出于报告的目的,BusinessUnit,Manager和BusinessUnitManager只是用于访问基本信息的表,需要分组的实际信息包含在Log表中,我的最终结果集应如下所示:

BusinessUnit.Name,
Log.Code,
Count(*) LogRecordsCount,
Emails (Comma separated list of Managers assigned to the Business Unit)

我一直在尝试使用CROSS APPLY获取逗号分隔的列,但无法正常工作,我当前的查询如下:

SELECT
L.BusinessUnit,
L.Code, 
COUNT(*) AS RecordsCount,
F.Emails
FROM [dbo].[LOG] AS L
INNER JOIN [dbo].[BusinessUnit] AS D ON L.BusinessUnit = D.ID
INNER JOIN [dbo].[BusinessUnitManager] AS DSO ON D.ID = DSO.BusinessUnit
CROSS APPLY
(
    SELECT STUFF((
    SELECT ',' + O.Email
    FROM [dbo].[Manager] AS O
    WHERE O.Id = DSO.IdManager
    ORDER BY O.Email ASC
    FOR XML PATH ('')), 1, 1, '')
) F(Emails)
GROUP BY L.BusinessUnit, L.Code, F.Emails

此查询的问题是返回重复的行,分配给该业务部门的每位经理电子邮件每行一行,而我的预期结果应该只有一行,其中一列包含所有经理电子邮件的逗号分隔列表。

当前结果:

+--------------+------+--------------+----------------------------+
| BusinessUnit | Code | RecordsCount |           Emails           |
+--------------+------+--------------+----------------------------+
| Americas     |   00 |           21 | americasmanager1@email.com |
| Americas     |   00 |           21 | americasmanager2@email.com |
| Asia         |   10 |            5 | asiamanager1@email.com     |
| Asia         |   10 |            5 | asiamanager2@email.com     |
+--------------+------+--------------+----------------------------+

预期结果:

+--------------+------+--------------+-------------------------------------------------------+
| BusinessUnit | Code | RecordsCount |                        Emails                         |
+--------------+------+--------------+-------------------------------------------------------+
| Americas     |   00 |           21 | americasmanager1@email.com,americasmanager2@email.com |
| Asia         |   10 |            5 | asiamanager1@email.com,asiamanager2@email.com         |
+--------------+------+--------------+-------------------------------------------------------+

感谢您的帮助

2 个答案:

答案 0 :(得分:1)

您很亲密,只需分两个步骤进行操作即可:

1)将您的东西存储到临时表中

Event::operator+=()

2)使用自己的外部应用程序将电子邮件填充到一栏中

SELECT
L.BusinessUnit,
L.Code, 
O.Emails
into #tmp
FROM [dbo].[LOG] AS L
INNER JOIN [dbo].[BusinessUnit] AS D ON L.BusinessUnit = D.ID
INNER JOIN [dbo].[BusinessUnitManager] AS DSO ON D.ID = DSO.BusinessUnit
JOIN [Manager] AS O ON O.Id = DSO.IdManager
GROUP BY L.BusinessUnit, L.Code, O.Emails

答案 1 :(得分:-1)

SELECT
    L.BusinessUnit,
    L.Code, 
    COUNT(*) AS RecordsCount,
    (
        SELECT STUFF((
        SELECT ',' + O.Email
        FROM [dbo].[Manager] AS O
            INNER JOIN [dbo].[BusinessUnitManager] AS DSO ON O.Id = DSO.IdManager 
        WHERE 
            DSO.BusinessUnit = D.ID
        ORDER BY O.Email ASC
        FOR XML PATH ('')), 1, 1, '')
    ) as Emails
FROM [dbo].[LOG] AS L
    INNER JOIN [dbo].[BusinessUnit] AS D ON L.BusinessUnit = D.ID
GROUP BY L.BusinessUnit, L.Code, D.ID