在 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) 查询

如何在 C# 中创建动态参数化 SQL 查询字符串

如何在 sql 中创建查询以将句子切成单词并将它们按频率添加到新表中

SQL查询在MySQL中创建一个表来存储tweet

根据条件在Access的SQL查询中创建日期字段