sql >> Databasteknik >  >> RDS >> PostgreSQL

Varför kombinerar PostgreSQL serier på ett felaktigt sätt?

Det är en egenhet om hur flera set-returnerande funktioner exekveras när de anropas i SELECT -lista. Du förväntar dig att resultatet ska vara korsprodukten av de två, men det är inte så det fungerar. Det är faktiskt den lägsta gemensamma multipeln av radantalet av de två.

Se:

Jämför:

test=>     SELECT generate_series(1,3) aval, generate_series(1,4) bval;
 aval | bval 
------+------
    1 |    1
    2 |    2
    3 |    3
    1 |    4
    2 |    1
    3 |    2
    1 |    3
    2 |    4
    3 |    1
    1 |    2
    2 |    3
    3 |    4
(12 rows)

test=>     SELECT generate_series(1,3) aval, generate_series(1,3) bval;
 aval | bval 
------+------
    1 |    1
    2 |    2
    3 |    3
(3 rows)

Av denna anledning bör du på PostgreSQL 9.2 och senare använda LATERAL frågor där du anropar set-returnerande funktioner i FROM klausul:

test=>     SELECT aval, bval FROM generate_series(1,3) aval CROSS JOIN LATERAL generate_series(1,3) bval;
 aval | bval 
------+------
    1 |    1
    1 |    2
    1 |    3
    2 |    1
    2 |    2
    2 |    3
    3 |    1
    3 |    2
    3 |    3
(9 rows)

test=>     SELECT aval, bval FROM generate_series(1,3) aval CROSS JOIN LATERAL generate_series(1,4) bval;
 aval | bval 
------+------
    1 |    1
    1 |    2
    1 |    3
    1 |    4
    2 |    1
    2 |    2
    2 |    3
    2 |    4
    3 |    1
    3 |    2
    3 |    3
    3 |    4
(12 rows)

På äldre versioner kan du använda en subquery-in-FROM för att undvika att ha flera SRF:er i en SELECT-term:

test=> SELECT generate_series(1,3) aval, bval FROM (SELECT generate_series(1,4)) AS x(bval);
 aval | bval 
------+------
    1 |    1
    2 |    1
    3 |    1
    1 |    2
    2 |    2
    3 |    2
    1 |    3
    2 |    3
    3 |    3
    1 |    4
    2 |    4
    3 |    4
(12 rows)


  1. Xampp Kommer inte att starta MySQL-servern på Mac OSX?

  2. Webbseminarium:Nya funktioner i Postgres 12 [Följa upp]

  3. Ansluta oraklet i Android-applikationen

  4. Hur infogar man i en tabell som anger ett DEFAULT-värde för varje kolumn?