我增加了更多的「測試數據」進行測試和說明。主要計算是將輸入範圍分解成三部分(其中一些無意義,並在最後階段被淘汰 - 當輸入範圍嚴格與主記錄重疊時,最多達到三個輸入範圍方向)。
爲了提高效率,最好每個輸入行只訪問一次。因此,我並不是使用union all
(最簡單的路線),而是同時創建所有三個子範圍和相應的標誌,結果有9列,而不是三個子範圍和標誌。然後我使用unpivot
將它們放入不同的行中。
with
test_data (id, lowerlimit, upperlimit) as (
select 1, 5, 10 from dual union all ---Master Record
select 2, 8, 12 from dual union all
select 3, 3, 8 from dual union all
select 4, 8, 9 from dual union all
select 5, 11, 15 from dual union all
select 6, 2, 5 from dual union all
select 7, 1, 14 from dual
)
-- end of test data (not part of the solution)
-- SQL query begins BELOW THIS LINE (use your actual table name)
select id, lowerlimit, upperlimit, flag
from (
select id,
t.lowerlimit as x1, least(t.upperlimit, m.ll) as y1, 'n' as f1,
greatest(t.lowerlimit, m.ll) as x2, least(t.upperlimit, m.ul) as y2, 'y' as f2,
greatest(t.lowerlimit, m.ul) as x3, t.upperlimit as y3, 'n' as f3
from test_data t cross join
(select lowerlimit ll, upperlimit ul
from test_data
where id = 1
) m
where t.id != 1
)
unpivot ((lowerlimit, upperlimit, flag)
for (x, y, f) in ((x1, y1, f1), (x2, y2, f2), (x3, y3, f3)))
where lowerlimit < upperlimit
order by id, lowerlimit -- if needed
;
輸出:
ID LOWERLIMIT UPPERLIMIT FLAG
-- ---------- ---------- ----
2 8 10 y
2 10 12 n
3 3 5 n
3 5 8 y
4 8 9 y
5 11 15 n
6 2 5 n
7 1 5 n
7 5 10 y
7 10 14 n
10 rows selected.
所以主記錄將始終具有ID = 1,它會一直存在?然後:一個時間間隔可能需要分成三次(例如2到15的時間間隔)。對?如果一個記錄只是「觸及」主記錄,比如2到5,那麼它是如何處理的?標誌'n',結果是單行,還是標誌'y',我們顯示從5到5的記錄? – mathguy
此外,是原始記錄的旗幟,還是最終的碎片?該文本說「分配標誌的記錄」(似乎暗示原始記錄),但輸出顯示分配給每一塊的標誌。 – mathguy
@mathguy是的..如果忘記提及從2到15間隔的測試用例。同樣在目標表中,我們可以避免主記錄 –