sql >> Database >  >> RDS >> PostgreSQL

Waarom combineert PostgreSQL series op een verkeerde manier?

Het is een eigenaardigheid van hoe meerdere set-returning-functies worden uitgevoerd wanneer ze worden aangeroepen in de SELECT -lijst. Je verwacht dat het resultaat het kruisproduct van de twee is, maar zo werkt het niet. Het is eigenlijk het kleinste gemene veelvoud van het aantal rijen van de twee.

Zie:

Vergelijk:

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)

Om deze reden moet u op PostgreSQL 9.2 en hoger LATERAL . gebruiken queries waarbij je set-returning functies aanroept in de FROM clausule:

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)

Op oudere versies kunt u een subquery-in-FROM gebruiken om te voorkomen dat u meerdere SRF's in een SELECT-term heeft:

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. Correcte instelling van databaseverbindingspool database.yml voor single-threaded Rails-toepassingen

  2. MySQL-connector voor Python

  3. NoClassDefFoundError krijgen tijdens het gebruik van Proguard en SQLcipher in Android

  4. Hoe te schrijven met BCP naar een externe SQL Server?