以表格格式返回数据的查询(多列)

时间:2016-03-15 22:06:55

标签: sql formatting

我想知道tSQL是否可以以表格格式返回我的数据。我从来没有见过SQL这样做,也许这是这项工作的错误工具,但如果有可能的话,它会省去一些步骤。现在我正在将数据导出到Excel并使用VBA创建表格。

说我有这张桌子:

CREATE TABLE temp_table
(SomeDate nvarchar(20), SomeEvent nvarchar(10)) 

INSERT INTO temp_table
VALUES 
,(convert(nvarchar(20), '1/1/2016', 23), 'foo') 
,(convert(nvarchar(20), '1/1/2016', 23), 'bar') 
,(convert(nvarchar(20), '1/1/2016', 23), 'left') 
,(convert(nvarchar(20), '1/1/2016', 23), 'right') 
,(convert(nvarchar(20), '1/1/2016', 23), 'in' )
,(convert(nvarchar(20), '1/1/2016', 23), 'out') 
,(convert(nvarchar(20), '1/2/2016', 23), 'foo') 
,(convert(nvarchar(20), '1/2/2016', 23), 'in') 
,(convert(nvarchar(20), '1/2/2016', 23), 'right' )
,(convert(nvarchar(20), '1/2/2016', 23), 'out' )
,(convert(nvarchar(20), '1/3/2016', 23), 'foo' )
,(convert(nvarchar(20), '1/3/2016', 23), 'right' )
,(convert(nvarchar(20), '1/3/2016', 23), 'left' )
,(convert(nvarchar(20), '1/3/2016', 23), 'bar' )
,(convert(nvarchar(20), '1/3/2016', 23), 'in' )
,(convert(nvarchar(20), '1/3/2016', 23), 'something') 

SQL可以为我构建一个看起来像这样的输出吗?

1/1/2016    1/2/2016    1/3/2016
  foo         foo         foo
  bar                     bar
  left                    left
  right       right       right
  in          in          in
  out         out    
                        something

我一直在摆弄UNION连接和聚合函数,但是我不能把它们放在一起以使其工作。我需要排序的数据,以及没有任何数据的空白字段,如图所示。我的数据可能会有很大差异 - 不同数量的SomeDates,使用这个简单的例子,以及SomeEvent的不同值。

可能?我吠叫错了树吗?

1 个答案:

答案 0 :(得分:2)

您可以使用排名功能和PIVOT

来执行此操作
;with cte AS (SELECT DISTINCT SomeEvent, DENSE_RANK() OVER(ORDER BY SomeEvent) AS RN
              FROM temp_table
              )
    ,cte2 AS (SELECT a.*, b.RN
              FROM temp_table a
              JOIN cte b
                ON a.SomeEvent = b.SomeEvent
              )
SELECT [2016-01-01],[2016-01-02],[2016-01-03]
FROM cte2
PIVOT (MAX (SomeEvent) FOR SomeDate IN ([2016-01-01],[2016-01-02],[2016-01-03]))pvt

演示:SQL Fiddle

为了使其动态化,您将查询所有日期并将它们存储在列表中,并使用这样的动态SQL:

DECLARE @sql VARCHAR(MAX) 
       ,@cols VARCHAR(MAX) = STUFF((SELECT DISTINCT ',' +   QUOTENAME(SomeDate)                     
                                    FROM temp_table                         
                                    FOR XML PATH(''), TYPE).value('.', 'VARCHAR(MAX)') 
                                    ,1,1,'')

SET @sql = ';with cte AS (SELECT DISTINCT SomeEvent, DENSE_RANK() OVER(ORDER BY SomeEvent) AS RN
              FROM temp_table
              )
    ,cte2 AS (SELECT a.*, b.RN
              FROM temp_table a
              JOIN cte b
                ON a.SomeEvent = b.SomeEvent
              )
SELECT '+@cols+'
FROM cte2
PIVOT (MAX (SomeEvent) FOR SomeDate IN ('+@cols+'))pvt'
EXEC (@sql)

演示:SQL Fiddle2