1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92
|
DECLARE
w_todo NUMBER(10,0) ;
BEGIN
MERGE INTO t_products_tripart d
USING (
SELECT s.id, s.upper, s.lower,
(SELECT count(id) FROM t_products_tripart WHERE rn IS NOT NULL) +
ROW_NUMBER() OVER(ORDER BY
CASE WHEN s.lower = (SELECT lower FROM t_products_tripart WHERE rn = (SELECT MAX(rn) FROM t_products_tripart)) THEN 0 ELSE 1 END,
-- n_next_lower DESC,
n_next_upper, s.id) AS rn
FROM t_products_tripart s
JOIN (
SELECT s.upper, s.lower, COUNT(dupp.upper) AS n_next_upper
FROM t_products_tripart s
LEFT JOIN t_products_tripart dupp ON dupp.upper = s.lower AND dupp.rn IS NULL
WHERE s.upper = (
-- next upper to use
SELECT upper FROM (
SELECT upper, n_with_same_lower, n_upper,
ROW_NUMBER() OVER(ORDER BY n_upper DESC, n_with_same_lower DESC) AS rn
FROM (
SELECT DISTINCT upper,
CASE WHEN upper = (SELECT lower FROM t_products_tripart WHERE rn = (SELECT MAX(rn) FROM t_products_tripart)) THEN 0 ELSE 1 END as p,
SUM(
CASE WHEN
lower = (SELECT lower FROM t_products_tripart WHERE rn = (SELECT MAX(rn) FROM t_products_tripart))
THEN 1 ELSE 0 END) OVER(PARTITION BY upper) AS n_with_same_lower,
COUNT( id) OVER(PARTITION BY upper) AS n_upper
FROM t_products_tripart
WHERE rn IS NULL
)
)
WHERE rn = 1
)
GROUP BY s.upper, s.lower
) d ON s.lower = d.lower AND s.upper = d.upper
) s
ON (s.id = d.id)
WHEN MATCHED THEN
UPDATE SET rn = s.rn
;
SELECT COUNT(*) INTO w_todo FROM t_products_tripart WHERE rn IS NULL ;
WHILE (w_todo > 0)
LOOP
MERGE INTO t_products_tripart d
USING (
SELECT s.id, s.upper, s.lower,
(SELECT count(id) FROM t_products_tripart WHERE rn IS NOT NULL) +
ROW_NUMBER() OVER(ORDER BY
CASE WHEN s.lower = (SELECT lower FROM t_products_tripart WHERE rn = (SELECT MAX(rn) FROM t_products_tripart)) THEN 0 ELSE 1 END,
n_next_lower,
s.id) AS rn
FROM t_products_tripart s
JOIN (
SELECT s.upper, s.lower
, COUNT( CASE WHEN dlow.lower NOT IN (SELECT upper FROM t_products_tripart WHERE rn IS NOT NULL) THEN dlow.upper END ) AS n_next_lower
FROM t_products_tripart s
LEFT JOIN t_products_tripart dlow ON dlow.lower = s.lower AND dlow.rn IS NULL
WHERE s.upper = (
-- next upper to use
SELECT upper FROM (
SELECT upper, n_with_same_lower, n_upper,
ROW_NUMBER() OVER(ORDER BY n_with_same_lower DESC, n_upper DESC) AS rn
FROM (
SELECT DISTINCT upper,
CASE WHEN upper = (SELECT lower FROM t_products_tripart WHERE rn = (SELECT MAX(rn) FROM t_products_tripart)) THEN 0 ELSE 1 END as p,
SUM(
CASE WHEN
lower = (SELECT lower FROM t_products_tripart WHERE rn = (SELECT MAX(rn) FROM t_products_tripart))
THEN 1 ELSE 0 END) OVER(PARTITION BY upper) AS n_with_same_lower,
COUNT( id) OVER(PARTITION BY upper) AS n_upper
FROM t_products_tripart
WHERE rn IS NULL
)
)
WHERE rn = 1
)
GROUP BY s.upper, s.lower
) d ON s.lower = d.lower AND s.upper = d.upper
) s
ON (s.id = d.id)
WHEN MATCHED THEN
UPDATE SET rn = s.rn
;
SELECT COUNT(*) INTO w_todo FROM t_products_tripart WHERE rn IS NULL ;
END LOOP ;
COMMIT ;
END ;
/ |
Partager