【问题标题】:Group_Concat in pairs of nthGroup_Concat 成对的第 n 个
【发布时间】:2018-05-10 13:23:24
【问题描述】:

我有一个通常group_concat 的查询。我需要知道dbo.group_concat 是否能够将查询结果配对为 3 对(例如)。

例如:

select size, pattern, dbo.group_concat(mass) mass 
from labels 
group by size, pattern

结果是

Size Pattern Mass 
-----------------------------------------------------------
234  ZYL     22.43,55.32,33.24,22.53,56.32,40.32,50.21,32.21
234  ZA      50.00,56.23,21.23,50.21

我想要这个结果

Size Pattern  Mass
--------------------------------
234  ZYL      22.43,55.32,33.24
234  ZYL      22.53,56.32,40.32
234  ZYL      50.21,32.21
234  ZA       50.00,56.23,21.23
234  ZA       50.21 

【问题讨论】:

  • 背后的逻辑是什么?我不认为有这样的功能是SSMS...
  • 将您的GROUP BY 条件更改为您需要的任何条件。
  • 你在使用 MySQL?
  • 我正在使用 MSSQL 2008 。按语法分组将在前 2 列上分组,但我需要将质量值分成 3 对(在其他作品中,在每个第 3 个分隔符之后)。这纯粹是为了简化数据,因为某些结果中有 100 个值。
  • SQL Server 默认没有dbo.group_concat。您可能正在使用 groupconcat.codeplex.com 或者您可能正在使用其他东西。你使用的东西会影响它提供的能力。

标签: sql sql-server group-by concat sql-server-group-concat


【解决方案1】:

如果我们有一个group ID 列,这可以很容易地完成。此列将每三行分组,按[mass] 值对数据进行排序。由于我们没有这样的列,我们需要计算它。具体步骤如下:

  1. 我们正在使用ROW_NUMBER 函数对行进行排序并知道哪三个结果行构成一个组
  2. 然后,我们使用递归公用表表达式(没什么太复杂的) - 只需获取每个 size, pattern 实体的第一行,然后加入下一行......然后加入下一行,直到我们全部获得它们李>

这是上面的完整工作示例:

DECLARE @DataSource TABLE
(
    [size] VARCHAR(12)
   ,[pattern] VARCHAR(12)
   ,[mass] DECIMAL(9,2)
);


INSERT INTO @DataSource ([size], [pattern], [mass])
VALUES (234, 'ZYL', 22.43)
      ,(234, 'ZYL', 55.32)
      ,(234, 'ZYL', 33.24)
      ,(234, 'ZYL', 22.53)
      ,(234, 'ZYL', 56.32)
      ,(234, 'ZYL', 40.32)
      ,(234, 'ZYL', 50.21)
      ,(234, 'ZYL', 32.21)
      --
      ,(234, 'ZA', 50.00)
      ,(234, 'ZA', 56.23)
      ,(234, 'ZA', 21.23)
      ,(234, 'ZA', 50.21);

WITH DataSource AS 
(
    SELECT *
          ,ROW_NUMBER() OVER (PARTITION BY [size], [pattern] ORDER BY [mass]) AS [RowID]
    FROM @DataSource
),
RecursiveDataSource AS
(
    SELECT [size], [pattern], [mass], [RowID]
          ,1 AS [Group]
    FROM DataSource
    WHERE [RowID] = 1
    UNION ALL
    SELECT A.*
          ,R.[Group] + CASE WHEN (A.[rowID] - 1) % 3 = 0 THEN 1 ELSE 0 END
    FROM DataSource A
    INNER JOIN RecursiveDataSource R
        ON A.[size] = R.[size]
        AND A.[pattern] = R.[pattern]
        AND A.[RowID] - 1 = R.[rowID]
)
SELECT *
FROM RecursiveDataSource
ORDER BY [pattern], [RowID];

现在,在最后的SELECT 中,我们只需要添加您的初始代码,但也可以按[group] 列分组:

SELECT [size], [pattern], [dbo].[group_concat] ([mass])
FROM RecursiveDataSource
GROUP BY [size], [pattern], [Group];

在我的系统中,上面的结果如下:

一些注意事项:

  • 我按mass 值排序值(在您的示例中,您不是)- 这完全取决于您;您可以将排序更改为您需要的任何内容,甚至在ROW_NUMBER 函数的ORDER BY 子句中使用SELECT 1 来获得一些随机排序;
  • 对大表使用递归 CTE 会导致性能不佳;一定要先用你的真实数据测试过代码;
  • 我系统上的concatenate SQL CLR 函数允许设置顺序;在我的例子中,我使用RowID 值连接了这些行;如果您的函数不允许指定这样的顺序,则您依赖于它背后的 .net 代码,因此您可以在最终 CSV 列表中获得不同的值顺序。

【讨论】:

猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-06-14
  • 1970-01-01
  • 2021-04-09
  • 2020-04-01
相关资源
最近更新 更多