Awalnya, saya tidak bisa melihat solusi yang lebih elegan daripada membuat tabel sementara.
Saya berpikir, betapa canggungnya dialek SQL Oracle:
- Mengapa tidak JIKA TABEL ADA HAPUS TABEL?
- Mengapa saya harus melakukan EXECUTE IMMEDIATE dengan string? Mengapa saya tidak bisa melakukan DROP TABLE TEMP sendiri?
- Mengapa saya tidak dapat memiliki ORDER BY tanpa bersarang dalam tanda kurung di ANCHOR?
- Mengapa saya tidak dapat memiliki ORDER BY pada SELECT rekursif setelah UNION ALL?
- SQL WITH membutuhkan standarisasi. Dialek basis data lainnya tidak mengharuskan nama kolom dikurung pada pernyataan WITH. Jika Anda tidak melakukannya, Anda mendapatkan kesalahan ALIAS yang tidak berarti, pada titik penggabungan rekursif setelah UNION ALL.
- Pagination:Lihat di sini Tanpa LIMIT / OFFSET
DECLARE
v_c NUMBER;
BEGIN
SELECT COUNT(*) INTO v_c FROM user_tables WHERE TABLE_NAME = 'TEMP';
IF v_c = 1 THEN
EXECUTE IMMEDIATE 'DROP TABLE TEMP';
END IF;
END;
CREATE TABLE TEMP AS (
SELECT * FROM (
SELECT JOBMST_ID, JOBMST_NAME, JOBMST_PRNTID, JOBMST_TYPE
FROM TIDAL.JOBMST
WHERE JOBMST_PRNTID IS NOT NULL
ORDER BY JOBMST_PRNTID, JOBMST_NAME
)
);
WITH J1(JOBMST_ID, JOBMST_NAME, JOBMST_PRNTID, JOBMST_TYPE, LVL) AS (
SELECT * FROM (
SELECT JOBMST_ID, JOBMST_NAME, JOBMST_PRNTID, JOBMST_TYPE, 1
FROM TIDAL.JOBMST
WHERE JOBMST_PRNTID IS NULL
ORDER BY JOBMST_NAME
)
UNION ALL
SELECT J2.JOBMST_ID, J2.JOBMST_NAME, J2.JOBMST_PRNTID, J2.JOBMST_TYPE, J1.LVL + 1
FROM TEMP J2
INNER JOIN J1 ON J2.JOBMST_PRNTID = J1.JOBMST_ID
WHERE J2.JOBMST_PRNTID IS NOT NULL
)
SEARCH DEPTH FIRST BY JOBMST_ID SET DISP_SEQ
SELECT *
FROM J1
ORDER BY DISP_SEQ;
Kemudian (ahli matematika di Forum Komunitas Oracle) menunjukkan kepada saya SEARCH DEPTH FIRST saya seharusnya hanya oleh JOBMST_NAME.
Kemudian semuanya jatuh pada tempatnya:
WITH J1(JOBMST_ID, JOBMST_NAME, JOBMST_PRNTID, JOBMST_TYPE, LVL) AS (
SELECT JOBMST_ID, JOBMST_NAME, JOBMST_PRNTID, JOBMST_TYPE, 1
FROM TIDAL.JOBMST
WHERE JOBMST_PRNTID IS NULL
UNION ALL
SELECT J2.JOBMST_ID, J2.JOBMST_NAME, J2.JOBMST_PRNTID, J2.JOBMST_TYPE, J1.LVL + 1
FROM TIDAL.JOBMST J2
INNER JOIN J1 ON J2.JOBMST_PRNTID = J1.JOBMST_ID
WHERE J2.JOBMST_PRNTID IS NOT NULL
)
SEARCH DEPTH FIRST BY JOBMST_NAME SET DISP_SEQ
SELECT *
FROM J1
ORDER BY DISP_SEQ