Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/26.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在datetime SQL列中按日期和8小时间隔对这些日期进行分组和计数?_Sql_Sql Server - Fatal编程技术网

如何在datetime SQL列中按日期和8小时间隔对这些日期进行分组和计数?

如何在datetime SQL列中按日期和8小时间隔对这些日期进行分组和计数?,sql,sql-server,Sql,Sql Server,我有一个带有列visit\u date的表,它是一个datetime对象,格式为YYYY-MM-DD HH:MI:SS,如下所示: visit_date |visit_id -------------------|----- 2010-11-01 00:02:00|92314 2010-11-01 23:05:21|23498 2010-11-01 12:42:31|12343 2010-11-02 05:13:21|79881 2010-11-02 14:35:15|22134

我有一个带有列
visit\u date
的表,它是一个
datetime
对象,格式为
YYYY-MM-DD HH:MI:SS
,如下所示:

visit_date         |visit_id
-------------------|-----
2010-11-01 00:02:00|92314
2010-11-01 23:05:21|23498
2010-11-01 12:42:31|12343
2010-11-02 05:13:21|79881
2010-11-02 14:35:15|22134
2010-11-02 16:12:23|12348
2010-11-03 01:22:44|12384
2010-11-03 05:23:41|12394
2010-11-03 15:13:55|99384
我希望在该日期按日期和8小时窗口分组,以便:

interval           |count
-------------------|-----
2010-11-01 00:00:00|1
2010-11-01 08:00:00|2
2010-11-01 16:00:00|3
2010-11-02 00:00:00|4
2010-11-02 08:00:00|5
2010-11-02 16:00:00|6
2010-11-03 00:00:00|7
2010-11-03 08:00:00|8
2010-11-03 16:00:00|9
我最初的查询(仅使用日期)是:

但这只是按日期分组

是否有一种推荐的方法来获取每天每个间隔的间隔计数?我见过使用
DATEADD
DATEPART
的实现,但不确定在这种情况下哪种实现最有意义


谢谢

使用
交叉应用
形成4个移位边界值,然后使用
案例表达式中的值
生成
分组依据

SELECT
      case
         when visit_date >= s1 and visit_date < s2 then s1 
         when visit_date >= s2 and visit_date < s3 then s2
         when visit_date >= s3 and visit_date < s4 then s3 
      end as shift
    , count(1) as count
FROM mytable
CROSS APPLY (
    select 
          cast(CAST(visit_date as DATE)as datetime) s1
        , dateadd(hh,8,cast(CAST(visit_date as DATE)as datetime)) s2
        , dateadd(hh,16,cast(CAST(visit_date as DATE)as datetime)) s3
        , dateadd(hh,24,cast(CAST(visit_date as DATE)as datetime)) s4  
    ) ca
GROUP BY
      case
         when visit_date >= s1 and visit_date < s2 then s1 
         when visit_date >= s2 and visit_date < s3 then s2
         when visit_date >= s3 and visit_date < s4 then s3 
      end
ORDER BY shift

将小时数添加到您的分组和计数中:

SELECT 
  CAST(visit_date as DATE), 
  HOUR(visit_date)/8 as ival8h
  count(1) as count
FROM table
  GROUP BY CAST(visit_date as DATE), HOUR(visit_date)/8
  ORDER BY CAST(visit_date as DATE)
hour函数返回传递日期的小时数,除以8得到间隔的整数,因此0到7变为0,8到16变为1,以此类推

如果您希望将其作为一个固定在8小时一轮的时间重新乘以8,并将其格式化为NN:00:00,或将其添加到日期,因此:

SELECT 
  DATEADD(hour, (HOUR(visit_date)/8)*8, CAST(CAST(visit_date as DATE) as DATETIME) as quantized_date,
  count(1) as count
FROM table
  GROUP BY DATEADD(hour, (HOUR(visit_date)/8)*8, CAST(CAST(visit_date as DATE) as DATETIME)
  ORDER BY CAST(visit_date as DATE)
这基本上是将时间向下舍入到较小的8小时市场,并将其添加到午夜。在日期上需要(可能)两次强制转换,因为DATEADD不会在日期上增加小时,只会在datetime上增加小时,但我们需要强制转换到日期,以便将tine元素固定到午夜


如果希望在没有发生事件的时间段中有一个日期和0计数,请使用数字表或行生成器,创建一个日期序列,将真实数据左键连接到其中,然后按假日期对真实数据进行分组计数。我认为SQL Server中的标准方法是使用
dateadd()
datediff()


如何使
计数
列?我看不出它有什么逻辑,汉克斯,这很有道理。要重新格式化它,我是否可以简单地将
HOUR(visit_date)/8替换为
格式(HOUR(visit_date)/00:00')
-格式遵循.net格式系统,因此任何文本都被语音标记包围,第一个00用于将数字填充成两位数,也就是说,您可以选择
日期添加
(小时(访问日期)/8)*8
小时到
演员阵容(访问日期为日期)
(午夜)如果您想将其保留为日期时间,或者进一步使用它,请添加第二个查询来实现上述功能
SELECT 
  CAST(visit_date as DATE), 
  HOUR(visit_date)/8 as ival8h
  count(1) as count
FROM table
  GROUP BY CAST(visit_date as DATE), HOUR(visit_date)/8
  ORDER BY CAST(visit_date as DATE)
SELECT 
  DATEADD(hour, (HOUR(visit_date)/8)*8, CAST(CAST(visit_date as DATE) as DATETIME) as quantized_date,
  count(1) as count
FROM table
  GROUP BY DATEADD(hour, (HOUR(visit_date)/8)*8, CAST(CAST(visit_date as DATE) as DATETIME)
  ORDER BY CAST(visit_date as DATE)
select dateadd(hour, 0, 3 * (datediff(hour, 0, visit_date) / 3)) as day_hour8,
       count(*)
from t
group by dateadd(hour, 0, 3 * (datediff(hour, 0, visit_date) / 3))
order by day_hour8;