Oracle 12 से, आप MATCH_RECOGNIZE
. का उपयोग कर सकते हैं :
SELECT cat,
month,
COUNT(*)
FROM (
SELECT t.*,
TRUNC( "DATE", 'MM' ) AS month
FROM table_name t
)
MATCH_RECOGNIZE(
PARTITION BY cat, month
ORDER BY "DATE", version
ONE ROW PER MATCH
AFTER MATCH SKIP TO LAST change_code
PATTERN ( strt change_code )
DEFINE
change_code AS change_code.some_code <> strt.some_code
)
GROUP BY cat, month
जो, नमूना डेटा के लिए:
CREATE TABLE table_name ( CAT, NR, "DATE", VERSION, SOME_CODE ) AS
SELECT 'ABC', 123, TIMESTAMP '2009-02-19 00:00:00 UTC', 1, 'OPP' FROM DUAL UNION ALL
SELECT 'ABC', 456, TIMESTAMP '2009-03-18 00:00:00 UTC', 1, 'ZUM' FROM DUAL UNION ALL
SELECT 'ABC', 444, TIMESTAMP '2009-03-18 00:00:00 UTC', 1, 'ZUM' FROM DUAL UNION ALL
SELECT 'ABC', 444, TIMESTAMP '2009-03-18 00:00:00 UTC', 2, 'MUZ' FROM DUAL UNION ALL
SELECT 'ABC', 456, TIMESTAMP '2009-04-18 00:00:00 UTC', 2, 'XXX' FROM DUAL UNION ALL
SELECT 'ABC', 456, TIMESTAMP '2009-04-18 00:00:00 UTC', 3, 'XXX' FROM DUAL UNION ALL
SELECT 'ABC', 456, TIMESTAMP '2009-04-18 00:00:00 UTC', 4, 'UIO' FROM DUAL UNION ALL
SELECT 'ABC', 456, TIMESTAMP '2009-05-18 00:00:00 UTC', 5, 'RQA' FROM DUAL UNION ALL
SELECT 'DEF', 637, TIMESTAMP '2018-02-16 00:00:00 UTC', 1, 'FAW' FROM DUAL UNION ALL
SELECT 'DEF', 789, TIMESTAMP '2018-02-17 00:00:00 UTC', 1, 'WER' FROM DUAL UNION ALL
SELECT 'GHI', 248, TIMESTAMP '2018-02-17 00:00:00 UTC', 1, 'QWE' FROM DUAL UNION ALL
SELECT 'GHI', 248, TIMESTAMP '2019-02-17 00:00:00 UTC', 2, 'PPP' FROM DUAL UNION ALL
SELECT 'GHI', 357, TIMESTAMP '2020-02-16 00:00:00 UTC', 1, 'FFF' FROM DUAL UNION ALL
SELECT 'GHI', 420, TIMESTAMP '2020-02-16 00:00:00 UTC', 1, 'QDS' FROM DUAL UNION ALL
SELECT 'GHI', 357, TIMESTAMP '2020-02-16 00:00:00 UTC', 2, 'GGG' FROM DUAL UNION ALL
SELECT 'GHI', 357, TIMESTAMP '2020-02-16 00:00:00 UTC', 3, 'LLL' FROM DUAL UNION ALL
SELECT 'GHI', 357, TIMESTAMP '2020-02-16 00:00:00 UTC', 4, 'LLL' FROM DUAL UNION ALL
SELECT 'GHI', 357, TIMESTAMP '2020-08-16 00:00:00 UTC', 4, 'FFF' FROM DUAL UNION ALL
SELECT 'GHI', 357, TIMESTAMP '2020-10-16 00:00:00 UTC', 5, 'ZZZ' FROM DUAL
आउटपुट:
यदि आप परिवर्तन देखना चाहते हैं तो आप इसका उपयोग कर सकते हैं:
SELECT *
FROM (
SELECT t.*,
TRUNC( "DATE", 'MM' ) AS month
FROM table_name t
)
MATCH_RECOGNIZE(
PARTITION BY cat, month
ORDER BY "DATE", version
MEASURES
MATCH_NUMBER() AS mn,
FIRST( some_code ) AS change_from,
LAST( some_code ) AS change_to
ONE ROW PER MATCH
AFTER MATCH SKIP TO LAST change_code
PATTERN ( strt change_code )
DEFINE
change_code AS change_code.some_code <> strt.some_code
)
कौन सा आउटपुट:
db<>fiddle यहां
यदि "एक महीने के भीतर" के लिए आपकी आवश्यकता यह है कि आप परिवर्तन चाहते हैं, जहां पिछली पंक्ति और बदली हुई पंक्ति के बीच अधिकतम एक महीने का अंतर है, भले ही पंक्तियाँ दो अलग-अलग कैलेंडर महीनों में हों, (केवल होने वाले परिवर्तनों के बजाय) उसी कैलेंडर माह में) तो आप इसका उपयोग कर सकते हैं:
SELECT cat,
TRUNC( change_date, 'MM' ) AS month,
COUNT(*)
FROM table_name
MATCH_RECOGNIZE(
PARTITION BY cat
ORDER BY "DATE", version
MEASURES
LAST( "DATE" ) AS change_date
ONE ROW PER MATCH
AFTER MATCH SKIP TO LAST change_code
PATTERN ( strt change_code )
DEFINE
change_code AS (
change_code.some_code <> strt.some_code
AND MONTHS_BETWEEN( change_code."DATE", strt."DATE" ) <= 1
)
)
GROUP BY cat, TRUNC( change_date, 'MM' )
कौन सा आउटपुट:
db<>fiddle यहां