sql >> Databasteknik >  >> RDS >> Oracle

Rekursiv subquerying med sortering

Till en början kunde jag inte se en mer elegant lösning än att skapa ett tempbord.

Jag tänkte, vilken besvärlig dialekt av SQL Oracle är:

  1. Varför inte OM TABELL FINNS DELETE TABELL?
  2. Varför måste jag göra EXECUTE OMEDELBART med en sträng? Varför kan jag inte bara göra DROP TABLE TEMP på egen hand?
  3. Varför kan jag inte få ORDER BY utan att kapsla inom parentes på ANCHOR?
  4. Varför kan jag inte ha ORDER BY på rekursivt SELECT efter UNION ALL?
  5. SQL MED behöver standardiseras. Andra databasdialekter kräver inte att kolumnnamn sätts inom parentes på WITH-satsen. Om du inte gör det får du ett meningslöst ALIAS-fel, vid punkten för den rekursiva anslutningen efter UNION ALL.
  6. Sökning:Se här No 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;

Sedan (mathguy på Oracle Community Forum) påpekade för mig att mitt SÖKDJUP FÖRST bara borde ha varit av JOBMST_NAME.

Då faller allt på plats:

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. MVC4:UserIsInRole - Kan inte ansluta till SQL Server-databasen

  2. Beräkna löpande total / löpande balans

  3. Hur man skapar användare med superanvändarprivilegier i PostgreSQL

  4. Hur ökar man MySQL-anslutningar (max_connections)?