sql >> Database teknologi >  >> RDS >> PostgreSQL

Postgres analog til CROSS APPLY i SQL Server

I Postgres 9.3 eller senere brug en LATERAL deltage:

SELECT v.col_a, v.col_b, f.*  -- no parentheses here, f is a table alias
FROM   v_citizenversions v
LEFT   JOIN LATERAL f_citizen_rec_modified(v.col1, v.col2) f ON true
WHERE  f.col_c = _col_c;

Hvorfor LEFT JOIN LATERAL ... ON true ?

  • Optegnelsen returneret fra funktionen har kolonner sammenkædet

Til ældre versioner , der er en meget enkel måde at opnå det jeg synes på du forsøger med en sæt-retur-funktion (RETURNS TABLE eller RETURNS SETOF record ELLER RETURNS record ):

SELECT *, (f_citizen_rec_modified(col1, col2)).*
FROM   v_citizenversions v

Funktionen beregner værdier én gang for hver række i den ydre forespørgsel. Hvis funktionen returnerer flere rækker, ganges de resulterende rækker tilsvarende. Alle parenteser er syntaktisk nødvendige at dekomponere en rækketype. Tabelfunktionen kunne se sådan ud:

CREATE OR REPLACE FUNCTION f_citizen_rec_modified(_col1 int, _col2 text)
  RETURNS TABLE(col_c integer, col_d text) AS
$func$
SELECT s.col_c, s.col_d
FROM   some_tbl s
WHERE  s.col_a = $1
AND    s.col_b = $2
$func$ LANGUAGE sql;

Du skal pakke dette ind i en underforespørgsel eller CTE, hvis du vil anvende en WHERE klausul, fordi kolonnerne ikke er synlige på samme niveau. (Og det er alligevel bedre for ydeevnen, fordi du forhindrer gentagen evaluering for hver outputkolonne i funktionen):

SELECT col_a, col_b, (f_row).*
FROM (
   SELECT col_a, col_b, f_citizen_rec_modified(col1, col2) AS f_row
   FROM   v_citizenversions v
   ) x
WHERE (f_row).col_c = _col_c;

Der er flere andre måder at gøre dette på eller noget lignende. Det hele afhænger af, hvad du præcist vil have.



  1. er der nogen funktion til at oversætte data i sql

  2. Slet en Database Mail Profile (SSMS)

  3. MySQL automatisk caste/konvertere en streng til et tal?

  4. PostgreSQL:kodningsproblemer på Windows, når du bruger psql kommandolinjeværktøj