Oracle
 sql >> Teknologi Basis Data >  >> RDS >> Oracle

Subquery Rekursif dengan penyortiran

Awalnya, saya tidak bisa melihat solusi yang lebih elegan daripada membuat tabel sementara.

Saya berpikir, betapa canggungnya dialek SQL Oracle:

  1. Mengapa tidak JIKA TABEL ADA HAPUS TABEL?
  2. Mengapa saya harus melakukan EXECUTE IMMEDIATE dengan string? Mengapa saya tidak bisa melakukan DROP TABLE TEMP sendiri?
  3. Mengapa saya tidak dapat memiliki ORDER BY tanpa bersarang dalam tanda kurung di ANCHOR?
  4. Mengapa saya tidak dapat memiliki ORDER BY pada SELECT rekursif setelah UNION ALL?
  5. 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.
  6. 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



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Bagaimana saya bisa mengatasi ORA-00911:kesalahan karakter tidak valid?

  2. Kembalikan baris dengan nilai maksimal satu kolom per grup

  3. Dua pernyataan PLSQL dengan awal dan akhir, berjalan dengan baik secara terpisah tetapi tidak bersama-sama?

  4. Oracle 11g:Default ke nilai statis saat kueri tidak menghasilkan apa-apa

  5. TNSPING OK tapi sqlplus memberikan ORA-12154?