Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/oracle/10.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
Sql 选择按午夜时间分组的数据_Sql_Oracle_Group By - Fatal编程技术网

Sql 选择按午夜时间分组的数据

Sql 选择按午夜时间分组的数据,sql,oracle,group-by,Sql,Oracle,Group By,我有一张像这样的桌子: ID TIMEVALUE ----- ------------- 1 06.07.15 06:43:01,000000000 2 06.07.15 12:17:01,000000000 3 06.07.15 18:21:01,000000000 4 06.07.15 23:56:01,000000000 5 07.07.15 04:11:01,000000000 6 07

我有一张像这样的桌子:

ID       TIMEVALUE
-----    -------------
1        06.07.15 06:43:01,000000000
2        06.07.15 12:17:01,000000000
3        06.07.15 18:21:01,000000000
4        06.07.15 23:56:01,000000000
5        07.07.15 04:11:01,000000000
6        07.07.15 10:47:01,000000000
7        07.07.15 12:32:01,000000000
8        07.07.15 14:47:01,000000000
我想按特殊时间对这些数据进行分组。 我当前的查询如下所示:

SELECT TO_CHAR(TIMEVALUE, 'YYYY\MM\DD'), COUNT(ID), 
  SUM(CASE WHEN TO_CHAR(TIMEVALUE, 'HH24MI') <=700 THEN 1 ELSE 0 END) as morning,
  SUM(CASE WHEN TO_CHAR(TIMEVALUE, 'HH24MI') >700 AND TO_CHAR(TIMEVALUE, 'HH24MI') <1400 THEN 1 ELSE 0 END) as daytime,
  SUM(CASE WHEN TO_CHAR(TIMEVALUE, 'HH24MI') >=1400 THEN 1 ELSE 0 END) as evening FROM Table
WHERE TIMEVALUE >= to_timestamp('05.07.2015','DD.MM.YYYY')
GROUP BY TO_CHAR(TIMEVALUE, 'YYYY\MM\DD')
因此,在同一天的0-7点、7-14点和14-24点可以进行分组 但我现在的问题是: 我怎样才能在午夜集合

例如,从第二天的6-14、14-23和23-6点开始计数

我希望你能理解我的问题。如果有更好的解决方案,欢迎您甚至改进我的上部查询。

编辑:现在已测试:

关键是通过调整分组,以便将早上6点之前的任何内容与前一天分组。在那之后,计数是相当直接的

SELECT TO_CHAR(CASE WHEN EXTRACT(HOUR FROM timevalue) < 6
                    THEN timevalue - 1
                    ELSE timevalue
                    END, 'YYYY\MM\DD') AS day, 
       COUNT(*) AS overall, 
       SUM(CASE WHEN EXTRACT(HOUR FROM timevalue) >= 6 AND EXTRACT(HOUR FROM timevalue) < 14
                THEN 1 ELSE 0 END) AS morning,
       SUM(CASE WHEN EXTRACT(HOUR FROM timevalue) >= 14 AND EXTRACT(HOUR FROM timevalue) < 23
                THEN 1 ELSE 0 END) AS daytime,
       SUM(CASE WHEN EXTRACT(HOUR FROM timevalue) < 6 OR EXTRACT(HOUR FROM timevalue) >= 23
                THEN 1 ELSE 0 END) AS evening
FROM my_table
WHERE timevalue >= TO_TIMESTAMP('05.07.2015','DD.MM.YYYY')
GROUP BY TO_CHAR(CASE WHEN EXTRACT(HOUR FROM timevalue) < 6
                    THEN timevalue - 1
                    ELSE timevalue
                    END, 'YYYY\MM\DD');

先从时间值中减去1天,然后再减去小于“06:00”的时间:


也许您可以通过一些重新格式化或透视来实现这一点:

WITH spans AS 
    (SELECT TIMESTAMP '2015-01-01 00:00:00' + LEVEL * INTERVAL '1' HOUR AS start_time
    FROM dual
    CONNECT BY TIMESTAMP '2015-01-01 00:00:00' + LEVEL * INTERVAL '1' HOUR < LOCALTIMESTAMP),
t AS 
    (SELECT start_time, lead(start_time, 1) OVER (ORDER BY start_time) AS end_time, ROWNUM AS N
    FROM spans
    WHERE EXTRACT(HOUR FROM start_time) IN (6,14,23))
SELECT N, start_time, end_time, COUNT(*) AS ID_COUNT,
    DECODE(EXTRACT(HOUR FROM start_time), 6,'morning', 14,'daytime', 23,'evening') AS daytime
FROM t
    JOIN YOUR_TABLE WHERE TIMEVALUE BETWEEN start_time AND end_time
GROUP BY N;

当然,在我的示例中,初始时间值“2015-01-01 00:00:00”必须小于表中的最小日期。

将GROUP BY调整为\u CHARTIMEVUE,'YYYY\MM\DD',例如1小时。您的意思是类似GROUP BY to \u CHARTIMEVUE-6/24,'YYYYYY\MM\DD HH24'?太好了,我会测试一下
select TO_CHAR(day, 'YYYY\MM\DD') day, COUNT(ID) cnt, 
    SUM(case when '23' < tvh or  tvh <= '06' THEN 1 ELSE 0 END) as midnight,
    SUM(case when '06' < tvh and tvh <= '14' THEN 1 ELSE 0 END) as daytime,
    SUM(case when '14' < tvh and tvh <= '23' THEN 1 ELSE 0 END) as evening
  FROM (
    select id, to_char(TIMEVALUE, 'HH24') tvh,
        trunc(case when (to_char(timevalue, 'hh24') <= '06') 
                   then timevalue - interval '1' day  
                   else timevalue end) day
      from t1
    )
  GROUP BY day
WITH spans AS 
    (SELECT TIMESTAMP '2015-01-01 00:00:00' + LEVEL * INTERVAL '1' HOUR AS start_time
    FROM dual
    CONNECT BY TIMESTAMP '2015-01-01 00:00:00' + LEVEL * INTERVAL '1' HOUR < LOCALTIMESTAMP),
t AS 
    (SELECT start_time, lead(start_time, 1) OVER (ORDER BY start_time) AS end_time, ROWNUM AS N
    FROM spans
    WHERE EXTRACT(HOUR FROM start_time) IN (6,14,23))
SELECT N, start_time, end_time, COUNT(*) AS ID_COUNT,
    DECODE(EXTRACT(HOUR FROM start_time), 6,'morning', 14,'daytime', 23,'evening') AS daytime
FROM t
    JOIN YOUR_TABLE WHERE TIMEVALUE BETWEEN start_time AND end_time
GROUP BY N;