【问题标题】:CROSS APPLY to return comma separated values along with GROUP BYCROSS APPLY 与 GROUP BY 一起返回逗号分隔值
【发布时间】:2019-01-10 05:01:33
【问题描述】:

我正在处理一个查询以返回一个报告,该报告将对每个业务单位的日志记录进行分组,以及分配给每个业务单位的经理的逗号分隔列表,所以基本上有 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         |
+--------------+------+--------------+-------------------------------------------------------+

感谢您的帮助

【问题讨论】:

  • 一些示例数据在这里可能会有所帮助。
  • 我想你想改变你的东西的逻辑。 SELECT ',' + O.Email FROM [dbo].[Manager] AS O JOIN [dbo].[BusinessUnitManager] AS M ON M.IdManager = O.Id WHERE M.BusinessUnit = DSO.BusinessUnit ORDER BY O.Email FOR XML PATH('') 之类的东西 当然,当前的逻辑会为每个经理生成单独的行,但这应该基于业务单位加入......旁注,我认为在常规子查询中交叉应用没有优势,你会如果它只是一个常规子查询,则不必将其包含在 GROUP BY 中...
  • @TimBiegeleisen 我已经编辑以显示一些示例数据
  • @ZLK 谢谢,我在 STUFF 查询中添加了 INNER JOIN,现在按预期工作

标签: sql-server tsql


【解决方案1】:

你很接近,只需分两步完成:

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

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

2) 对自己使用外部应用将电子邮件填充在一列中

select BusinessUnit,Code, F.Emails from #tmp t 
outer apply( 
     SELECT STUFF(( SELECT ',' + inner.Email 
     FROM #tmp inner 
     WHERE t.Id = inner. 
     ORDER BY O.Email ASC 
     FOR XML PATH ('')), 1, 1, '') 
) F(Emails) 
group by BusinessUnit,Code

【讨论】:

    【解决方案2】:
    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
    

    【讨论】:

      猜你喜欢
      • 2014-12-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-10-20
      • 2011-11-18
      • 2010-09-19
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多