在SQL Server中动态生成列

时间:2017-07-25 12:23:23

标签: sql sql-server

我有以下SQL。我用它来返回一个帐户组的每日接收时间。

SELECT 
    ACCT_GRP_ID,
    CONCAT(CONCAT(FORMAT(GETDATE(),'dd-MM-yyyy'), ' '),    
    AS_RECEPTION_TIMES.RECEPTION_WINDOW_START) AS RECEPTION_START,
    CONCAT(CONCAT(FORMAT(GETDATE(),'dd-MMyyyy'), ' '), 
    AS_RECEPTION_TIMES.RECEPTION_WINDOW_END) AS RECEPTION_END
FROM 
    AS_RECEPTION_TIMES
JOIN 
    AS_AS_RECEPTION_CONF ON AS_RECEPTION_TIMES.ACCT_STAT_RECEPTION_CONFIG_ID = AS_AS_RECEPTION_CONF.ID
WHERE 
    ACCT_GRP_ID > 1

返回以下结果:

enter image description here

如您所见,我有不同的帐户组,有多个接收时间。 现在我想对帐户进行分组,因此每个ACCT_GRP_ID只有一行,所有接收开始和结尾都在其后面的列中。

我怎么能意识到这一点?

1 个答案:

答案 0 :(得分:1)

1静态解决方案

如果您事先知道数据中会有多少列(RECEPTION_START / RECEPTION_END对),那么您可以生成所有列/值组合并使用简单的{构建最终表格{ {1}}。

这些是我使用的测试数据:

enter image description here

这是代码:

PIVOT

输出以下结果:

enter image description here

2动态解决方案

如果您更喜欢处理任意数量的--temporary table with sample data create table #tmp (ACCT_GRP_ID int, RECEPTION_START DATETIME, RECEPTION_END DATETIME) --populate test data insert into #tmp values (26, '20170725 00:09:00', '20170725 00:09:15'),(26, '20170725 00:09:15', '20170725 00:09:30'),(26, '20170725 00:09:30', '20170725 00:09:45'),(26, '20170725 00:09:45', '20170725 00:10:00'),(27, '20170725 00:15:00', '20170725 00:15:30'),(27, '20170725 00:15:30', '20170725 00:16:00') --create the new combinations of columns and values and then pivot the data select * from ( select tt.ACCT_GRP_ID, tt.col, tt.val from( select *, 'RECEPTION_START_' + cast(t.ID as nvarchar(max)) as col ,RECEPTION_START as val FROM (SELECT * , ROW_NUMBER() OVER ( PARTITION by ACCT_GRP_ID Order by RECEPTION_START ) AS ID FROM #tmp) t union all select *, 'RECEPTION_END_' + cast(t.ID as nvarchar(max)) as col ,RECEPTION_END as val FROM (SELECT * , ROW_NUMBER() OVER (PARTITION by ACCT_GRP_ID Order by RECEPTION_START) AS ID FROM #tmp) t ) tt ) ttt PIVOT ( max(val) for Col in ( [RECEPTION_START_1], [RECEPTION_END_1], [RECEPTION_START_2], [RECEPTION_END_2], [RECEPTION_START_3], [RECEPTION_END_3], [RECEPTION_START_4], [RECEPTION_END_4] ) ) AS pvt / RECEPTION_START列的动态解决方案,则可以使用动态sql。请注意,此解决方案可能会导致SQL注入,性能问题以及通常与动态sql相关的所有问题。

在第二个解决方案中,我更改了前两行测试数据设置第1行RECEPTION_END = 24和第2行ACCT_GRP_ID = 25

此更改显示结果中的列数不同(将有两个ACCT_GRP_ID / RECEPTION_START对而不是4对:

enter image description here

RECEPTION_END

这是结果集:

enter image description here