【问题标题】:T-SQL grouping with dynamic column number使用动态列号进行 T-SQL 分组
【发布时间】:2012-08-07 15:28:27
【问题描述】:

假设我有一个像这样的一维表:

TBL_1
[ Task  ][ Entity ][ Timespan ]
[ TASK1 ][  ID1   ][    3     ]
[ TASK2 ][  ID2   ][    4     ]
[ TASK2 ][  ID1   ][    5     ]
[ TASK1 ][  ID2   ][    6     ]

我如何将它变成像这样的 2D 视图:

[ Entity ][ TASK1 ][ TASK2 ]
[  ID1   ][   3   ][   5   ]
[  ID2   ][   6   ][   4   ]

鉴于任务的数量应该是动态的?

我目前的解决方案是这样的:

SELECT A.Entity, B.Task TASK1, C.Task TASK2
FROM (SELECT DISTINCT ENTITY FROM TBL_1) A
LEFT JOIN TBL_1 B
ON A.Entity = B.Entity AND B.Task = 'TASK1'
LEFT JOIN TBL_1 C
ON A.Entity = C.Entity AND C.Task = 'TASK2'

但这需要我对任务进行“硬编码”。我怎样才能使这个动态?

非常感谢!

【问题讨论】:

标签: sql-server database tsql dynamic relational-database


【解决方案1】:

您正在寻找PIVOT。为此,您可以使用 Dynamic SQL Pivot。此策略将在执行查询时获取要转换的列名:

DECLARE @cols AS NVARCHAR(MAX),
    @query  AS NVARCHAR(MAX)

select @cols = STUFF((SELECT distinct ',' + QUOTENAME(task) 
                    from t1
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

set @query = 'SELECT entity, ' + @cols + ' from 
             (
                select entity, task, timespan
                from t1
            ) x
            pivot 
            (
                min(timespan)
                for task in (' + @cols + ')
            ) p '

execute(@query)

SQL Fiddle with Demo

【讨论】:

  • 非常感谢,这正是我想要的!不过,我必须了解整个 STUFF/XML/PATH/PIVOT 的工作原理:-)
  • 有什么办法可以用这个做一个 SELECT ... FROM [THIS_SOLUTION_ENCAPSULATED]?视图和函数似乎不允许动态 SQL,我们不能从存储过程中选择
  • 你打算如何使用它?您可以将此代码放在存储过程中并从中获取数据。
  • 好吧,假设生成的(透视的)数据集被命名为 TBL_2,我希望能够执行类似 SELECT * FROM TBL_2 WHERE Entity LIKE 'ID%'Task1>20 之类的操作......现在我做了一个存储过程,但我不能在它上面,或者加入,或者我们用来在桌子上做的一切......现在没问题,但它会更......优雅。
  • @m6a-uds 您将希望查看将存储过程中的值插入到临时表中。看看使用OPENROWSET,有关于这样做的答案
【解决方案2】:

您也可以本着您所尝试的精神来做到这一点。但是,使用 group by 比您尝试的要简单得多:

SELECT ENTITY,
       max(case when t.task = 'Task1' then timespan end) as task1,
       max(case when t.task = 'Task2' then timespan end) as task2,
       . . .
FROM TBL_1 t
group by entity

要动态生成列,您需要使用动态 SQL。这真的是你想要的吗?

【讨论】:

  • 是的。我认为 OP 正在寻找一种方法来动态生成列别名作为过滤器
  • @swasheck 。 . .谢谢你。我的意思是在我回复时添加最后一条评论。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-10-22
  • 2022-01-18
  • 1970-01-01
  • 2020-11-19
  • 2013-08-07
相关资源
最近更新 更多