sql >> Databáze >  >> RDS >> PostgreSQL

Jaké je očekávané chování pro více funkcí vracejících sadu v klauzuli SELECT?

Postgres 10 nebo novější

přidá hodnoty null pro menší sady. Demo s generate_series() :

SELECT generate_series( 1,  2) AS row2
     , generate_series(11, 13) AS row3
     , generate_series(21, 24) AS row4;
row2 | row3 | row4
-----+------+-----
   1 |   11 |   21
   2 |   12 |   22
null |   13 |   23
null | null |   24

dbfiddle zde

Manuál pro Postgres 10 :

Pokud je ve výběrovém seznamu dotazu více než jedna funkce vracející sadu, chování je podobné tomu, co získáte vložením funkcí do jednoho LATERAL ROWS FROM( ... ) FROM -položka klauzule. Pro každý řádek základního dotazu existuje výstupní řádek používající první výsledek z každé funkce, poté výstupní řádek používající druhý výsledek atd. Pokud některé funkce vracení množin produkují méně výstupů než jiné, chybějící data se nahradí hodnotami null, takže celkový počet řádků vygenerovaných pro jeden podkladový řádek je stejný jako u funkce vracení množin, která vyprodukovala nejvíce výstupů. Funkce vracení množin tedy běží „v zamčeném kroku“, dokud nejsou všechny vyčerpány, a pak provádění pokračuje dalším spodním řádkem.

Tím končí tradičně zvláštní chování.

Postgres 9.6 nebo starší

Počet řádků výsledků (poněkud překvapivě!) je nejnižší společný násobek všech sad ve stejném SELECT seznam. (Funguje pouze jako CROSS JOIN pokud neexistuje společný dělitel pro všechny velikosti sady!) Demo:

SELECT generate_series( 1,  2) AS row2
     , generate_series(11, 13) AS row3
     , generate_series(21, 24) AS row4;
row2 | row3 | row4
-----+------+-----
   1 |   11 |   21
   2 |   12 |   22
   1 |   13 |   23
   2 |   11 |   24
   1 |   12 |   21
   2 |   13 |   22
   1 |   11 |   23
   2 |   12 |   24
   1 |   13 |   21
   2 |   11 |   22
   1 |   12 |   23
   2 |   13 |   24

dbfiddle zde

Dokumentováno v manuálu pro Postgres 9.6 kapitola Funkce SQL vracející sady , spolu s doporučením, jak se tomu vyhnout:

Poznámka:Klíčový problém s používáním funkcí vracení množin ve výběrovém seznamu místo FROM klauzule je, že umístění více než oneset-vracejících funkcí do stejného výběrového seznamu se nechová příliš rozumně. (Pokud tak učiníte, ve skutečnosti získáte počet výstupních řádků rovný nejmenšímu společnému násobku počtu řádků vytvořených každou funkcí vracející sadu. ) LATERAL syntaxe přináší nepřekvapivé výsledky při volání více funkcí vracejících sadu a obvykle by se měla používat místo toho.

Tučné zdůraznění moje.

Jediná funkce vracení sady je v pořádku (ale stále čistší v FROM seznam), ale více ve stejném SELECT seznam se nyní nedoporučuje. To byla užitečná funkce, než jsme měli LATERAL se připojí. Nyní je to pouze historický balast.

Související:

  • Paralelní unnest() a pořadí řazení v PostgreSQL
  • Uvolněte paralelně několik polí
  • Jaký je rozdíl mezi LATERAL JOIN a dílčím dotazem v PostgreSQL?


  1. C#:Ekvivalence datového typu Oracle s OracleDbType

  2. Jaký je rozdíl mezi spojením hash a spojením sloučení (Oracle RDBMS)?

  3. Jak připojit aplikaci pro Android k databázi MySQL?

  4. Jak vrátit výsledky dotazu jako seznam oddělený čárkami na serveru SQL – STRING_AGG()