2016-09-26 43 views
0

感谢我的一位朋友,我已经能够获得以下代码,该代码给出了基于30分钟差异的日期/时间计数。如果差值小于30分钟比数保持不变,否则,如果该值大于计数由1如何选择oracle的计数值sql

SELECT 
CASE 
     WHEN DATE2 - LAG(DATE2) over (PARTITION BY NAME, TRUNC(DATE2) ORDER BY DATE2) <= 1/48 
     THEN NULL 
     ELSE 1 
     END AS COUNT1 
FROM TABLE1 

什么我忘了问他有上升的是,已经被算作值开始计时的时间和结束时间,因为这可以让我锻炼花费了多长时间,但是我不确定如何根据上面的代码添加它,所以没有尝试任何东西。

我将不胜感激,如果有人可以请建议我如何可以带来这样的事情,因为SQL不是我最强的一点。

下面是一些示例数据:

NAME | DATE2 
Humpty Dumpty | 21-JUL-16 09:27:24 
Humpty Dumpty | 21-JUL-16 09:27:24 
Humpty Dumpty | 21-JUL-16 09:27:24 
Humpty Dumpty | 21-JUL-16 09:27:24 
Humpty Dumpty | 21-JUL-16 09:31:31 
Humpty Dumpty | 21-JUL-16 09:31:31 
Humpty Dumpty | 21-JUL-16 09:31:31 
Humpty Dumpty | 21-JUL-16 09:31:31 
Humpty Dumpty | 21-JUL-16 16:42:03 
Humpty Dumpty | 21-JUL-16 16:42:03 
Humpty Dumpty | 21-JUL-16 16:42:03 
Humpty Dumpty | 21-JUL-16 16:42:03 

当我运行上面的查询我得到如下:

Count1 
1 
(null) 
(null) 
(null) 
(null) 
(null) 
(null) 
(null) 
1 
(null) 
(null) 
(null) 

这给了我的价值,但我还需要知道的第一个值因为当1被计数并且下一个值之前的最后一个值被计数时。

从我上面的结果应该是这样的:

Count1 | Start_time | End_Time 
1 | 21-JUL-16 09:27:24 | 21-JUL-16 09:31:31 
1 | 21-JUL-16 16:42:03 | 21-JUL-16 16:42:03 

有一点需要指出的是,如果有半小时的同一天另一个值,然后开始时间也结束时间..

+0

您能否也显示一些示例数据?这会让你的问题(以及任何答案)对可能面临类似问题的其他人更有用。 –

+0

@TimBiegeleisen - 您可以在OTN上找到示例数据,其中几天前提出了原始问题。https://community.oracle.com/thread/3974725 – mathguy

+0

@mathguy感谢您的侦探工作,但问题应该至少包括一些示例数据。 –

回答

1

你想识别不同的组。因为您使用的是lag()方法,我会继续这样做。下一步是一个累计总和,然后聚合:

SELECT NAME, TRUNC(DATE2), MIN(DATE2), MAX(DATE2) 
FROM (SELECT t1.*, 
      SUM(COUNT1) OVER (PARTITION BY NAME, TRUNC(DATE2) ORDER BY DATE2) as grp 
     FROM (SELECT t1.*, 
        (CASE WHEN DATE2 - LAG(DATE2) over (PARTITION BY NAME, TRUNC(DATE2) ORDER BY DATE2) <= 1/48 
         THEN 0 ELSE 1 
        END) AS COUNT1 
      FROM TABLE1 t1 
      ) t1 
    ) t1 
GROUP BY NAME, TRUNC(DATE2), grp; 
+0

谢谢戈登,它的工作!只是出于好奇,我怎么还可以从滞后查询中添加触摸计数来给我一个总数,或者我可以根据名称,日期进行计数,这仍然会给我相同的数字 – user3191160

+0

@ user3191160。 。 。我不知道“触摸计数”是什么。应该将新问题作为评论中的问题提出。 –

+0

对不起,这不是一个新的问题,它的初始案例说明,给了我数... – user3191160

1
DATE2 

是当前行上的时间 - 在计算,这是结束时间

LAG(DATE2) over (PARTITION BY NAME, TRUNC(DATE2) ORDER BY DATE2) 

是前一行的时间(当按日期排序时) - 在计算中,这是开始时间

它确实如此简单。

我更新了以下内容(希望)以符合您的更新要求。

查询A使用LAG和LEAD函数来确定每行是否位于一组条目的开始位置(前一行> 30分钟差异)或一组条目的末尾(下一行> 30分钟差异)

查询乙然后将结果限制行,它们或者开始或结束行(一切仅仅是噪声)

最后每个开始和结束连接在一起成一个单一的一行。

WITH 
test_data (name, date2) AS 
    (SELECT 'Humpty Dumpty',TO_DATE('21/07/2016 09:27:24','DD/MM/YYYY HH24:MI:SS') FROM DUAL UNION ALL 
    SELECT 'Humpty Dumpty',TO_DATE('21/07/2016 09:27:24','DD/MM/YYYY HH24:MI:SS') FROM DUAL UNION ALL 
    SELECT 'Humpty Dumpty',TO_DATE('21/07/2016 09:27:24','DD/MM/YYYY HH24:MI:SS') FROM DUAL UNION ALL 
    SELECT 'Humpty Dumpty',TO_DATE('21/07/2016 09:27:24','DD/MM/YYYY HH24:MI:SS') FROM DUAL UNION ALL 
    SELECT 'Humpty Dumpty',TO_DATE('21/07/2016 09:31:31','DD/MM/YYYY HH24:MI:SS') FROM DUAL UNION ALL 
    SELECT 'Humpty Dumpty',TO_DATE('21/07/2016 09:31:31','DD/MM/YYYY HH24:MI:SS') FROM DUAL UNION ALL 
    SELECT 'Humpty Dumpty',TO_DATE('21/07/2016 09:31:31','DD/MM/YYYY HH24:MI:SS') FROM DUAL UNION ALL 
    SELECT 'Humpty Dumpty',TO_DATE('21/07/2016 09:31:31','DD/MM/YYYY HH24:MI:SS') FROM DUAL UNION ALL 
    SELECT 'Humpty Dumpty',TO_DATE('21/07/2016 09:40:00','DD/MM/YYYY HH24:MI:SS') FROM DUAL UNION ALL 
    SELECT 'Humpty Dumpty',TO_DATE('21/07/2016 09:40:00','DD/MM/YYYY HH24:MI:SS') FROM DUAL UNION ALL 
    SELECT 'Humpty Dumpty',TO_DATE('21/07/2016 16:42:03','DD/MM/YYYY HH24:MI:SS') FROM DUAL UNION ALL 
    SELECT 'Humpty Dumpty',TO_DATE('21/07/2016 16:42:03','DD/MM/YYYY HH24:MI:SS') FROM DUAL UNION ALL 
    SELECT 'Humpty Dumpty',TO_DATE('21/07/2016 16:42:03','DD/MM/YYYY HH24:MI:SS') FROM DUAL UNION ALL 
    SELECT 'Humpty Dumpty',TO_DATE('21/07/2016 16:45:03','DD/MM/YYYY HH24:MI:SS') FROM DUAL UNION ALL 
    SELECT 'Humpty Dumpty',TO_DATE('21/07/2016 16:45:03','DD/MM/YYYY HH24:MI:SS') FROM DUAL UNION ALL 
    SELECT 'Humpty Dumpty',TO_DATE('21/07/2016 18:00:03','DD/MM/YYYY HH24:MI:SS') FROM DUAL UNION ALL 
    SELECT 'Humpty Dumpty',TO_DATE('21/07/2016 18:00:03','DD/MM/YYYY HH24:MI:SS') FROM DUAL UNION ALL 
    SELECT 'Humpty Dumpty',TO_DATE('21/07/2016 18:00:03','DD/MM/YYYY HH24:MI:SS') FROM DUAL UNION ALL 
    SELECT 'ABC',TO_DATE('21/07/2016 18:00:03','DD/MM/YYYY HH24:MI:SS') FROM DUAL UNION ALL 
    SELECT 'ABC',TO_DATE('21/07/2016 18:10:03','DD/MM/YYYY HH24:MI:SS') FROM DUAL UNION ALL 
    SELECT 'ABC',TO_DATE('21/07/2016 18:50:03','DD/MM/YYYY HH24:MI:SS') FROM DUAL UNION ALL 
    SELECT 'ABC',TO_DATE('21/07/2016 18:51:03','DD/MM/YYYY HH24:MI:SS') FROM DUAL 
) 
SELECT 
name 
,TO_CHAR(start_time,'DD/MM/YYYY HH24:MI:SS')  start_time 
,TO_CHAR(end_time,'DD/MM/YYYY HH24:MI:SS')  end_time 
FROM 
--Query B 
(SELECT 
    name 
    ,date2          start_time 
    ,LEAD(date2) OVER (PARTITION BY name,TRUNC(date2) ORDER BY date2) end_time 
    ,start_flag 
    FROM 
    --Query A 
    (SELECT 
    name 
    ,date2 
    ,CASE 
     WHEN date2 - LAG(date2) OVER (PARTITION BY name, TRUNC(date2) ORDER BY date2) <= (1/48) 
     THEN 'N' 
     ELSE 'Y' 
    END          start_flag 
    ,CASE 
     WHEN LEAD(date2) OVER (PARTITION BY name, TRUNC(date2) ORDER BY date2) - date2 <= (1/48) 
     THEN 'N' 
     ELSE 'Y' 
    END          end_flag 
    FROM 
    test_data 
    ORDER BY 
    name 
    ,date2 
    ) 
    WHERE 1=1 
    AND (start_flag = 'Y' OR end_flag = 'Y') 
) 
WHERE start_flag = 'Y' 
; 
+0

谢谢克里斯蒂安,我已经写了查询给出了触摸的情况说明,但由于某种原因,(样本数据)第一个值不包括在内,我得到的开始时间为09:31:31,结束时间为16:42:03 .. – user3191160

+0

嗯。这比较棘手。让我有一个想法 –

+0

戈登的答案在下面是一个更好的答案,所以我给了它加1 –