2016-09-26 63 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 –