測試數據:
CREATE TABLE your_table (usr, start_date, end_date) AS (
SELECT 'A', DATE '2017-06-01', DATE '2017-06-03' FROM DUAL UNION ALL
SELECT 'B', DATE '2017-06-02', DATE '2017-06-04' FROM DUAL UNION ALL -- Overlaps previous
SELECT 'C', DATE '2017-06-06', DATE '2017-06-06' FROM DUAL UNION ALL
SELECT 'D', DATE '2017-06-07', DATE '2017-06-07' FROM DUAL UNION ALL -- Adjacent to previous
SELECT 'E', DATE '2017-06-11', DATE '2017-06-20' FROM DUAL UNION ALL
SELECT 'F', DATE '2017-06-14', DATE '2017-06-15' FROM DUAL UNION ALL -- Within previous
SELECT 'G', DATE '2017-06-22', DATE '2017-06-25' FROM DUAL UNION ALL
SELECT 'H', DATE '2017-06-24', DATE '2017-06-28' FROM DUAL UNION ALL -- Overlaps previous and next
SELECT 'I', DATE '2017-06-27', DATE '2017-06-30' FROM DUAL UNION ALL
SELECT 'J', DATE '2017-06-27', DATE '2017-06-28' FROM DUAL; -- Within H and I
查詢 :
SELECT SUM(days) AS total_days
FROM (
SELECT dt - LAG(dt) OVER (ORDER BY dt) + 1 AS days,
start_end
FROM (
SELECT dt,
CASE SUM(value) OVER (ORDER BY dt ASC, value DESC, ROWNUM) * value
WHEN 1 THEN 'start'
WHEN 0 THEN 'end'
END AS start_end
FROM your_table
UNPIVOT (dt FOR value IN (start_date AS 1, end_date AS -1))
)
WHERE start_end IS NOT NULL
)
WHERE start_end = 'end';
輸出:
TOTAL_DAYS
----------
25
說明:
SELECT dt, value
FROM your_table
UNPIVOT (dt FOR value IN (start_date AS 1, end_date AS -1))
這將UNPIVOT
表,以便開始和結束日期是在同一列(dt
)和給出的相應值開始時爲+1,結束日期爲-1。
SELECT dt,
SUM(value) OVER (ORDER BY dt ASC, value DESC, ROWNUM) AS total,
value
FROM your_table
UNPIVOT (dt FOR value IN (start_date AS 1, end_date AS -1))
將給出這些生成值的開始和結束日期以及累計總和。範圍的起始位置始終爲value=1
和total=1
,範圍的末尾始終爲total=0
。如果日期在一個範圍的中間,那麼它將有total>1
或value=-1
和total=1
。使用此項,如果乘以value
和total
,則範圍的開始爲value*total=1
,範圍的結尾爲value*total=0
,而其他任何值指示範圍中途的日期。
這是什麼這給出:
SELECT dt,
CASE SUM(value) OVER (ORDER BY dt ASC, value DESC, ROWNUM) * value
WHEN 1 THEN 'start'
WHEN 0 THEN 'end'
END AS start_end
FROM your_table
UNPIVOT (dt FOR value IN (start_date AS 1, end_date AS -1))
然後,您可以過濾掉的日期時start_end
是NULL
這會讓你有一張桌子交替start
和end
行,您可以使用LAG
計算天差數:
SELECT dt - LAG(dt) OVER (ORDER BY dt) + 1 AS days,
start_end
FROM (
SELECT dt,
CASE SUM(value) OVER (ORDER BY dt ASC, value DESC, ROWNUM) * value
WHEN 1 THEN 'start'
WHEN 0 THEN 'end'
END AS start_end
FROM your_table
UNPIVOT (dt FOR value IN (start_date AS 1, end_date AS -1))
)
WHERE start_end IS NOT NULL
所有你需要做的就是SUM
全部爲end - start
的差異;它給出了上面的查詢。
你能解釋一下所需的邏輯嗎? –
Didnt理解邏輯推導(服務使用天)。用戶'A'的樣本數據爲30天,但B爲25天。在你的問題中,你剛剛提到了30' –
,你解釋了它是結束日期和開始日期之間的基本區別,或者沒有正確解釋。 從表中選擇用戶,(end_date - start_date)作爲「Service Used」。 –