在 SQL 查询中创建行列
Posted
技术标签:
【中文标题】在 SQL 查询中创建行列【英文标题】:MAKE ROWS COLUMNS IN SQL QUERY 【发布时间】:2016-08-05 11:39:34 【问题描述】:我有疑问......
SELECT DATEPART(WEEK,idenddate) AS WeekNumber,
COUNT (*) as Total
FROM dbo.MyTable
Group by DATEPART(WEEK,idenddate)
ORDER BY WeekNumber
如何使周数成为列标题,将总计作为行。
【问题讨论】:
不用喊了。你已经知道你应该pivot
,为什么还要问?
toadworld.com/platforms/mysql/w/wiki/6349.pivoting
【参考方案1】:
--Create table
CREATE Table dbo.MyTable
(
idenddate datetime
);
GO
--Insert sample record in table
Insert into dbo.MyTable select getdate()
Go
Insert into dbo.MyTable select Dateadd(d,1,getdate())
Go
Insert into dbo.MyTable select Dateadd(d,2,getdate())
Go
Insert into dbo.MyTable select Dateadd(d,3,getdate())
Go
Insert into dbo.MyTable select Dateadd(d,4,getdate())
Go
Insert into dbo.MyTable select Dateadd(d,5,getdate())
Go
Insert into dbo.MyTable select Dateadd(d,6,getdate())
Go
Insert into dbo.MyTable select Dateadd(d,7,getdate())
Go
Insert into dbo.MyTable select Dateadd(d,12,getdate())
Go
--Optimize query
DECLARE @cols AS NVARCHAR(MAX),@colsHeader AS NVARCHAR(MAX), @query AS NVARCHAR(MAX)
--Create Column
select @cols = STUFF((SELECT ',' + 'W' + CONVERT(varchar(2), DATEPART(WEEK,idenddate))
from dbo.MyTable
Group by DATEPART(WEEK,idenddate)
order by DATEPART(WEEK,idenddate)
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
--Create Column Header
select @colsHeader = STUFF((SELECT ',' + 'W' + CONVERT(varchar(2), DATEPART(WEEK,idenddate)) + ' ''' + CONVERT(varchar(2), DATEPART(WEEK,idenddate)) +''''
from dbo.MyTable
Group by DATEPART(WEEK,idenddate)
order by DATEPART(WEEK,idenddate)
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set @query = 'SELECT ' + @colsHeader + ' from
(
SELECT ''W''+ Convert(varchar(2), DATEPART(WEEK,idenddate)) AS WeekNumber,
COUNT (*) as Total
FROM dbo.MyTable
Group by DATEPART(WEEK,idenddate)
) x
pivot
(
sum(Total)
for WeekNumber in (' + @cols + ')
) p '
EXEC(@query)
【讨论】:
【参考方案2】:你想要在这里做的是一个 Pivot。这是一个如何使用 Microsoft SQL Server 制作数据透视表的示例。不过,对于不同的服务器,可能还有其他方法。
https://blogs.msdn.microsoft.com/spike/2009/03/03/pivot-tables-in-sql-server-a-simple-sample/
另一种方法是创建一个存储过程并使用第一个表中的行生成一个临时表,然后为第一个表(生成列的表)的每一行循环遍历第二个表的值以创建一个临时数据透视表的插入语句。最后在临时数据透视表上选择您需要获取相关数据的任何过滤器。
【讨论】:
使用周数更容易,只需创建一个包含从 1 到 52 的工作日的临时表,而不是从另一个表中获取列数据。之前的算法仍然适用以上是关于在 SQL 查询中创建行列的主要内容,如果未能解决你的问题,请参考以下文章
如何在 python 中使用 sqlalchemy 在查询中创建 sql server 表变量
在 LibreOffice Base 中创建等效数据透视表的 SQL (HSQLDB) 查询