2010-07-16 73 views
4

我需要查询销售表并让结果表显示给定日期内不同时间段的细分。SQL Group按不同的时间段与日期

例如,该表具有以下字段:

 
Id (int), EntryDate (datetime), SaleReference (varchar) 

我想产生一个表,看起来像这样:

 
Date  Sales 9am-12pm Sales 12pm-3pm Sales 6pm-9pm 
---------- -------------- -------------- ------------- 
01-01-2010  10    20    6 
02-01-2010  12    16    3 
03-01-2010  43    11    2 

任何帮助将不胜感激。 谢谢

+0

Stephen - 您使用的是什么RDBMS和版本? – 2010-07-16 15:02:22

回答

5

假设下面的SQL Server。如果不是类似的逻辑可能适用于您的RDBMS,但可能有不同的功能从日期时间获取小时部分,而BETWEEN的行为可能也不同(在SQL Server中它是一个包容性范围)。

SELECT CAST([Date] AS Date) AS [Date], 
COUNT(CASE WHEN DATEPART(hour, [Date]) BETWEEN 9 AND 11 THEN 1 ELSE NULL END) 
    AS [Sales 9am-12pm], 
COUNT(CASE WHEN DATEPART(hour, [Date]) BETWEEN 12 AND 14 THEN 1 ELSE NULL END) 
    AS [Sales 12pm-3pm], 
COUNT(CASE WHEN DATEPART(hour, [Date]) BETWEEN 18 AND 20 THEN 1 ELSE NULL END) 
    AS [Sales 6pm-9pm] 
FROM Table 
GROUP BY CAST([Date] AS Date) /*For SQL2008*/ 

注意:早期版本的SQL Server需要更多的时间才能使日期部分超出日期时间。例如CAST(FLOOR(CAST(GETDATE() AS FLOAT)) AS DATETIME(从here

+0

您正在按日期分组,日期是日期时间。不幸的是,它不会正确分组。投射日期作为日期,并在选择放置相同的演员,它会被修复。 +1现在:) – 2010-07-16 14:53:23

+0

@Mike - 好点。现在修复。 – 2010-07-16 14:56:48

+0

这是完美的。谢谢Martin和Mike。 :-) – StephenLewes 2010-07-16 15:05:35

1

假设你的数据库支持这种日期数学的,你可以说:

CASE WHEN EntryDate - date(EntryDate) >= INTERVAL '9 hours' 
     AND EntryDate - date(EntryDate) < INTERVAL '12 hours' 
    THEN ... 

(这是PostgreSQL的间隔语法,顺便说一句...可能是非标准的。)但也有可能更优雅的做法。