sql >> Database >  >> RDS >> Oracle

Recursieve subquery's met sorteren

Aanvankelijk zag ik geen elegantere oplossing dan het maken van een tijdelijke tabel.

Ik zat te denken, wat een ongemakkelijk dialect van SQL Oracle is:

  1. Waarom niet ALS TABEL BESTAAT, TABEL VERWIJDEREN?
  2. Waarom moet ik IMMEDIATE UITVOEREN met een string? Waarom kan ik DROP TABLE TEMP niet gewoon zelf doen?
  3. Waarom kan ik geen ORDER BY gebruiken zonder tussen haakjes op ANCHOR te nesten?
  4. Waarom kan ik geen ORDER BY hebben op recursieve SELECT na UNION ALL?
  5. SQL WITH heeft standaardisatie nodig. Andere databasedialecten vereisen niet dat kolomnamen tussen haakjes staan ​​in de WITH-instructie. Als je dat niet doet, krijg je een betekenisloze ALIAS-fout, op het punt van de recursieve join na UNION ALL.
  6. Paginering:zie hier Geen 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;

Toen (mathguy op het Oracle Community Forum) wees me erop dat mijn ZOEKDIEPTE EERST gewoon door JOBMST_NAME had moeten zijn.

Dan valt alles op zijn plaats:

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. Reset het root-wachtwoord van MySQL op Windows

  2. PG::Fout:SELECT DISTINCT, ORDER BY-uitdrukkingen moeten in de selectielijst verschijnen

  3. Retourneer de korte maandnaam van een datum in Oracle

  4. Ontsnappen aan MySQL-wildcards