sql >> Databáze >  >> RDS >> Oracle

odborová klauzule v sql

Tato odpověď může být trochu nesourodá...

Oracle je velmi vybíravý s nastavenými operacemi. Každý sloupec musí mít stejný datový typ jako odpovídající sloupce ve druhém, třetím atd. dotazu.

Myslím váš druhý dotaz selže, protože Oracle vyhodnotí to_number() jako číslo předchozí k provedení union ale vyhodnotí ji jako "nulovou" po . Váš první dotaz byl úspěšný, protože první hodnota byla vyhodnocena jako "null-ness" a poté union dochází. To znamená, že pořadí hodnocení je:

  1. První výběr funkcí
  2. První výběr datových typů
  3. 2. výběr funkcí
  4. spojení
  5. 2. výběr datových typů

Pokusím se to dokázat krok za krokem, ale nejsem si jistý, zda to bude absolutní důkaz.

Oba následující dotazy

select 1 from dual union select '1' from dual;
select '1' from dual union select 1 from dual;

selže s následující chybou, protože neprobíhá žádná implicitní konverze.

Oba následující však uspějí

select null from dual union select '1' from dual;
select null from dual union select 1 from dual;

Pokud vybereme dump z těchto dvou dotazů se vrátí následující:

SQL> select dump(a)
  2    from ( select null a from dual union select '1' from dual );

DUMP(A)
-------------------------------------------------------------------

Typ=96 Len=1: 49
NULL

SQL> select dump(a)
  2    from ( select null a from dual union select 1 from dual );

DUMP(A)
-------------------------------------------------------------------

Typ=2 Len=2: 193,2
NULL

Jak můžete vidět, sloupce mají různé datové typy . První dotaz se znakem vrátí char a druhý vrátí číslo, ale pořadí bylo obráceno, s druhým select na prvním místě.

Nakonec, když se podíváme na dump vašeho prvního dotazu

SQL> select substr(dump(ename),1,35) a, substr(dump(loc),1,35) b
  2    from ( select ename,to_number(null) as loc from emp
  3            union
  4           select to_char(null),loc from dept
  5                  );

A                                   B
----------------------------------- -----------------------------------
Typ=1 Len=6: 104,97,104,97,104,97   NULL
NULL                                Typ=1 Len=6: 104,97,104,97,104,97

SQL>

Můžete vidět, že dump(to_number(null)) je null; ale varchar2 ne char se vrací, protože se jedná o datový typ vašeho sloupce. Je zajímavé poznamenat, že pořadí vrácených příkazů nebylo obráceno a že pokud byste tento dotaz vytvořili jako tabulku, oba sloupce by byly varchar2 .

Při rozhodování o datovém typu sloupce ve výběrovém dotazu Oracle vezme první známý datový typ a poté jej použije k výpočtu celkového datového typu. To by byl důvod, proč dotazy, kde první select byla nulová a jejich řádky byly obráceny.

Váš první dotaz byl úspěšný, protože první vyberte, select ename,to_number(null) from emp , "popisuje", jak bude výsledná sada vypadat. |varchar2|null| . Druhý dotaz pak přidá |varchar2|varchar2| , což nezpůsobuje žádné problémy.

Váš druhý dotaz se nezdařil, protože první vyberte select ename,to_number(null) from emp "popisuje" sadu výsledků jako varchar2, null . Potom se však pokusíte přidat číslo null a varchar2 do union .

Skok víry je v tom, že Oracle rozhoduje o tom, že to_number(null) je číslo předchozí do union a nevyhodnocovat ji jako „nulovost“ až poté. Opravdu nevím, jak otestovat, zda se to skutečně děje, protože nemůžete vytvořit objekt s null a jak jste si všimli, nemůžete jej vybrat ani.

Protože nemohu dokázat něco, co Oracle nepovoluje, pokusím se o empirický důkaz. Zvažte výsledky (nebo chyby) následujících dotazů.

SQL> select 1 as a from dual union select to_number(null) from dual;

         A
----------
         1


SQL> select '1' as a from dual union select to_number(null) from dual;
select '1' as a from dual union select to_number(null) from dual
       *
ERROR at line 1:
ORA-01790: expression must have same datatype as corresponding expression


SQL> select 1 as a from dual union select to_char(null) from dual;
select 1 as a from dual union select to_char(null) from dual
       *
ERROR at line 1:
ORA-01790: expression must have same datatype as corresponding expression


SQL> select '1' as a from dual union select to_char(null) from dual;

A
-
1

Zdá se, že demonstrují, že to_char a to_number , bez ohledu na to, zda jsou prováděny na hodnotě null, implicitně definují datový typ, který je následně vyhodnocen z hlediska vhodnosti v union , před jejich vyhodnocením na "nulovost"

Toto vysvětlení by také pokrývalo coalesce problém jako to_number(null) je číslo před je null.




  1. Pandy - write_frame to sqlite - datetime64[ns]

  2. Výběr mezi více tabulkami pomocí UNION

  3. vložit při aktualizaci duplicitního klíče

  4. SQL Server Triggers - seskupení podle transakcí