当前位置: 首页 > 知识库问答 >
问题:

SQL查询,它为合并多行的每个记录返回可变数量的列数

傅越
2023-03-14

我正在处理一个SQL查询,它应该返回每行具有相同或不同列数的数据

例如,我有以下来自 CTE 的数据,如下所示

 With CTE 
    As(

    select distinct
    b.Acc_Num,
a.Type
    ,a.START
     ,a.END
    ,a.USAGE
    from USAGE_DETAIL a 
    join Table2 b on b.CUSTOMER_TKN=a.CUSTOMER_TKN
    )
    Select * from CTE Order By Acc_num

结果是

Acc_Num  Type  Start     End       Usage
100       A    1/1/10    1/1/15    100.00
100       A    3/1/10    3/1/15    200.00
100       A    2/1/10    2/1/15    300.00
200       A    1/1/10    1/1/15    150.00
200       A    3/1/10    3/1/15    250.00
300       A    1/1/10    1/1/15    1000.00
300       A    3/1/10    3/1/15    2000.00

在上表中,每个Acc_Num我都有多条记录,我想以相同的Acc_num对所有记录进行分组,并根据每个acc_num的记录数创建其他列,结果应如下所示

100       A    1/1/10    1/1/15    100.00    3/1/10    3/1/15    200.00   2/1/10    2/1/15    300.00    
200       A    1/1/10    1/1/15    150.00    3/1/10    3/1/15    250.00
300       A    1/1/10    1/1/15    1000.00   3/1/10    3/1/15    2000.00

我不确定是否可以为单个数据集返回可变列数。

我可以知道解决这个问题的方法吗?

共有1个答案

孔安阳
2023-03-14

由于您正在旋转多个列(本系列中的3个),无论如何都需要动态SQL,因此单独使用动态SQL可能是最简单的。

DECLARE @Max INT = (SELECT COUNT(*) FROM (SELECT DISTINCT Acc_Num, Type FROM Records) T)
DECLARE @Index INT = 0, @Sql VARCHAR(MAX) = ''
SET @Sql = @Sql + 'SELECT Acc_Num, Type'
WHILE @Index < @Max BEGIN
    SET @Index = @Index + 1
    DECLARE @IndexChar VARCHAR(10) = CONVERT(VARCHAR(10), @Index)
    SET @Sql = @Sql + ',MAX(CASE WHEN RowNum = ' + @IndexChar + ' THEN [Start] ELSE NULL END) AS [Start' + @IndexChar + ']'
    SET @Sql = @Sql + ',MAX(CASE WHEN RowNum = ' + @IndexChar + ' THEN [End] ELSE NULL END) AS [End' + @IndexChar + ']'
    SET @Sql = @Sql + ',MAX(CASE WHEN RowNum = ' + @IndexChar + ' THEN [Usage] ELSE NULL END) AS [Usage' + @IndexChar + ']'
END
SET @Sql = @Sql + ' FROM (SELECT *, ROW_NUMBER() OVER (PARTITION BY Acc_Num ORDER BY Start) AS RowNum FROM Records) T GROUP BY Acc_Num, Type'
EXEC(@Sql)

这导致:

Acc_Num     Type Start1     End1       Usage1                Start2     End2       Usage2                Start3     End3       Usage3
----------- ---- ---------- ---------- --------------------- ---------- ---------- --------------------- ---------- ---------- ---------------------
100         A    2010-01-01 2015-01-01 100.00                2010-02-01 2015-02-01 300.00                2010-03-01 2015-03-01 200.00
200         A    2010-01-01 2015-01-01 150.00                2010-03-01 2015-03-01 250.00                NULL       NULL       NULL
300         A    2010-01-01 2015-01-01 1000.00               2010-03-01 2015-03-01 2000.00               NULL       NULL       NULL

更新

根据您的源数据,我将只替换子查询:

DECLARE @Max INT = (SELECT COUNT(*) FROM (
    SELECT DISTINCT
        b.Acc_Num,
        a.Type
    FROM USAGE_DETAIL a
        INNER JOIN Table2 b
            ON b.CUSTOMER_TKN=a.CUSTOMER_TKN
    ) T)
DECLARE @Index INT = 0, @Sql VARCHAR(MAX) = ''
SET @Sql = @Sql + 'SELECT Acc_Num, Type'
WHILE @Index < @Max BEGIN
    SET @Index = @Index + 1
    DECLARE @IndexChar VARCHAR(10) = CONVERT(VARCHAR(10), @Index)
    SET @Sql = @Sql + ',MAX(CASE WHEN RowNum = ' + @IndexChar + ' THEN [Start] ELSE NULL END) AS [Start' + @IndexChar + ']'
    SET @Sql = @Sql + ',MAX(CASE WHEN RowNum = ' + @IndexChar + ' THEN [End] ELSE NULL END) AS [End' + @IndexChar + ']'
    SET @Sql = @Sql + ',MAX(CASE WHEN RowNum = ' + @IndexChar + ' THEN [Usage] ELSE NULL END) AS [Usage' + @IndexChar + ']'
END
SET @Sql = @Sql + ' FROM (SELECT DISTINCT b.Acc_Num, a.Type, a.[START], a.[END], a.[USAGE], ROW_NUMBER() OVER (PARTITION BY b.Acc_Num ORDER BY a.[Start]) AS RowNum FROM USAGE_DETAIL a INNER JOIN Table2 b ON b.CUSTOMER_TKN=a.CUSTOMER_TKN) T GROUP BY Acc_Num, Type'
EXEC(@Sql)
 类似资料:
  • 问题内容: 桌子: 我的查询: 我收到“ MySQL子查询返回多个行”错误。 我知道此查询可以使用以下查询的解决方法: 然后使用php循环遍历结果并执行以下查询以获取和回显它: 但是我认为可能会有更好的解决方案? 问题答案: 简单的解决方法是在子查询中添加一个子句: 一个更好的选择(就性能而言)是使用联接:

  • 本文向大家介绍Mybatis查询多条记录并返回List集合的方法,包括了Mybatis查询多条记录并返回List集合的方法的使用技巧和注意事项,需要的朋友参考一下 实体对象如下: XML映射文件如下: 接口文件方法如下: 测试文件如下: 笔记: XML中只需resultType属性值为实体对象别名或全路径名。 mybatis会通过接口文件的返回值类型来判断返回的是集合还是对象。如果是对象,则按常规

  • 问题内容: 以下查询应返回从动漫中扮演角色的人物的姓名。但我收到以下错误: Blockquote ORA-01427:单行子查询返回多个行 提前致谢! 问题答案: 代替 使用 查询中有5个条件需要更改。 UPD 另外,您的查询等同于

  • 问题内容: 我负责处理的应用程序之一是每隔x秒检查一次Oracle DB表,以查看是否有新数据要处理(其他实时应用程序正在填充该数据)。 我们新的客户业务流程迫使我们的实时性在同一时间(比如说10000)同时每天填充几次记录来填充该表。下次我的应用程序检查是否有任何要处理的内容时,遇到10 000条记录并尝试对其进行处理。 它的设计不是很好,而且扩展性还不够好。快速解决方案是限制该应用程序从Ora

  • 问题内容: 我有一个具有相似结构和数据的示例表,如下所示: 表在每个学生出现的所有科目中都有每个学生的合并标记。 请帮助我,编写一个查询以提取每个学生( 不分学科/其他学生 )获得的MAXIMUM分数,如下所示: 按S_Name和Max(MARK_Value)分组 问题答案: 使用窗口功能 或者您可以使用相关的子查询

  • 问题内容: 我想创建一个postgres函数,该函数构建它动态返回的列集;简而言之,它应该包含一个键列表,每个键建立一个列,并返回包含该列集的记录。简单来说,这是代码: 这将生成看起来(大致)如下的查询: 当我尝试调用该函数时,出现以下错误: 当然,诀窍在于,标记为“标签1”和“标签2”的列取决于活动表内容中定义的活动集,我在调用该函数时无法预测这些活动。如何创建访问此信息的功能? 问题答案: S