如何在SQL Server中以31天为一个月按天进行数据透视
我有这张桌子:如何在SQL Server中以31天为一个月按天进行数据透视,sql,sql-server,sql-server-2008,pivot,pivot-table,Sql,Sql Server,Sql Server 2008,Pivot,Pivot Table,我有这张桌子: CREATE TABLE [dbo].[tblProducts] ( [CATEGORY_ID] [nvarchar](50) NULL, [PRODUCT] [nvarchar](50) NULL, [PRODUCTION_DATE] [datetime] NULL ) ON [PRIMARY] 我需要显示每月每天的总产品 日子应该以时间为中心 CATE 1 2 3 4 5 6 7.....30 (or 31) -->days of mon
CREATE TABLE [dbo].[tblProducts]
(
[CATEGORY_ID] [nvarchar](50) NULL,
[PRODUCT] [nvarchar](50) NULL,
[PRODUCTION_DATE] [datetime] NULL
) ON [PRIMARY]
我需要显示每月每天的总产品
日子应该以时间为中心
CATE 1 2 3 4 5 6 7.....30 (or 31) -->days of month
CATE1 1 5 --> count product by cate and day
CATE2 1 9
CATE3 5 10
请注意,生产日期为当前日期的上午6点
至下一日期上午5时59分
那是我的困难
请帮助我。以下是基本的透视查询:
Declare @month int = 1
; With data as (
Select [CATEGORY_ID], [PRODUCT], [PRODUCTION_DATE] = DATEPART(DAY, DATEADD(HOUR, -6, [PRODUCTION_DATE]))
, [PRODUCT_YEAR] = DATEPART(YEAR, [PRODUCTION_DATE]), [PRODUCTION_MONTH] = DATEPART(MONTH, [PRODUCTION_DATE]) From [dbo].[tblProducts]
--Where DATEPART(MONTH, DATEADD(HOUR, -6,[PRODUCTION_DATE])) = @month update if monthly/yearly query is needed
)
Select [CATEGORY_ID], [PRODUCTION_MONTH], [PRODUCTION_YEAR], [1], [2], [3], [4], [5], [6], [7], [8], [9], [10], [11], [12], [13], [14], [15], [16], [17], [18], [19], [20], [21], [22], [23], [24], [25], [26], [27], [28], [29], [30], [31]
From data
Pivot (
Count([PRODUCT])
For [PRODUCTION_DATE] In
([1], [2], [3], [4], [5], [6], [7], [8], [9], [10], [11], [12], [13], [14], [15], [16], [17], [18], [19], [20], [21], [22], [23], [24], [25], [26], [27], [28], [29], [30], [31])
) as piv
Order By [CATEGORY_ID], [PRODUCTION_YEAR], [PRODUCTION_MONTH]
我基本上抵消了6小时(-6)的时间。20150101 06:00变为午夜20150101 00:00,5:59变为23;前一天是59
PIVOT:要添加到@Julien的答案中,您可以使用CTE为每个月发送参数,而不必发送生产日期的月份和年份
SELECT
[CATEGORY_ID], [PRODUCTION_MONTH], [PRODUCTION_YEAR],
[1], [2], [3], [4], [5], [6], [7], [8], [9], [10],
[11], [12], [13], [14], [15], [16], [17], [18], [19], [20],
[21], [22], [23], [24], [25], [26], [27], [28], [29], [30], [31]
FROM
(SELECT [CATEGORY_ID], [PRODUCT],
DATEPART(DAY, DATEADD(HOUR, -6, [PRODUCTION_DATE])) AS [PRODUCTION_DAY]),
DATEPART(MONTH, DATEADD(HOUR, -6, [PRODUCTION_DATE])) AS [PRODUCTION_MONTH],
DATEPART(YEAR, DATEADD(HOUR, -6, [PRODUCTION_DATE])) AS [PRODUCTION_YEAR]
FROM [dbo].[tblProducts]) As tmpProducts
PIVOT (
Count([PRODUCT])
FOR [PRODUCTION_DAY] In
([1], [2], [3], [4], [5], [6], [7], [8], [9], [10],
[11], [12], [13], [14], [15], [16], [17], [18], [19], [20],
[21], [22], [23], [24], [25], [26], [27], [28], [29], [30], [31])
) as piv
ORDER BY [CATEGORY_ID], [PRODUCTION_YEAR], [PRODUCTION_MONTH]
示例输出:
CATEGORY_ID PRODUCTION_MONTH PRODUCTION_YEAR 1 2 3 4 5 6 7 8 ...
1 1 2014 12 14 5 17 16 27 4 15
1 2 2014 18 56 27 34 9 19 10 0
1 1 2015 13 12 23 43 24 20 15 20
1 2 2015 36 11 36 13 9 1 25 10
...
你的意思是
DATEPART
,不是DATAPART
?另外,为什么不在SELECT中添加生产日期的月份,以从表中的所有月份中透视出来,甚至可能是年份呢?Datepart已经修复了,但谢谢:)CTE路由只是一个子查询。不要把它看作一个邪恶的CTE。最佳实践建议先在子查询或CTE中准备包含3列的数据,然后从中透视数据。CTE只是更容易阅读和自己尝试。我不确定我是否理解你评论的最后一部分。对CTE没有任何异议。我只是建议您可以在不需要传递月份参数的情况下运行查询。再加上若几年出现在表中,你们将计算所有年份的同一个月。看我的答案。问题是关于6小时的补偿。不是我希望的那样“给我写代码”。我想提出要求的人会使它适应它的需要。真的!Julien,我把你的好代码也照字面理解了,提前考虑操作。跟上MSSQL的答案!回头见。CTE或子查询类似。我使用了一个参数,因为我认为他只是在寻找一个特定的月份。非常感谢。我已经复制并运行脚本以满足我的需要。