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

Venstre joinforbindelse med dynamisk tabelnavn afledt af kolonne

Uanset hvad, har du brug for dynamisk SQL.

Tabelnavn som givet parameter

CREATE OR REPLACE FUNCTION foo(_number int)
  RETURNS TABLE (cpa int, nr text, vym text) AS  -- adapt to actual data types!
$func$
BEGIN
   RETURN QUERY EXECUTE format(
      'SELECT t.cpa, substring(t.ku,'[0-9]+'), p.vym 
       FROM   public."table_data_C" t
       LEFT   JOIN %s p USING (cpa)'
     , 'pa' || _number
     );
END
$func$ LANGUAGE plpgsql;

Ring til:

SELECT * FROM foo(456887)

Generelt ville du rense tabelnavne med format ( %I ) for at undgå SQL-injektion. Med kun et integer som dynamisk input, der ikke er nødvendigt. Flere detaljer og links i dette relaterede svar:
INSERT med dynamisk tabelnavn i triggerfunktion

Datamodel

Der kan være gode grunde til datamodellen. Som partitionering / sharding eller separate privilegier ...
Hvis du ikke har en sådan god grund, kan du overveje at konsolidere flere tabeller med identisk skema til én og tilføje number som kolonne. Så behøver du ikke dynamisk SQL.

Overvej arv . Derefter kan du tilføje en betingelse på tableoid for kun at hente rækker fra en given undertabel:

SELECT * FROM parent_table
WHERE  tableoid = 'pa456887'::regclass

Vær dog opmærksom på begrænsninger for arv. Relaterede svar:

Navn på 2. tabel afhængig af værdi i 1. tabel

At udlede navnet på join-tabellen fra værdier i den første tabel komplicerer tingene dynamisk.

Kun for nogle få borde

LEFT JOIN hver på tableoid . Der er kun ét match pr. række, så brug COALESCE .

SELECT t.*, t.tbl, COALESCE(p1.vym, p2.vym, p3.vym) AS vym
FROM  (
   SELECT cpa, ('pa' || substring(ku,'[0-9]+'))::regclass AS tbl
   FROM   public."table_data_C"
   -- WHERE <some condition>
   ) t
LEFT   JOIN pa456887 p1 ON p1.cpa = t.cpa AND p1.tableoid = t.tbl
LEFT   JOIN pa456888 p2 ON p2.cpa = t.cpa AND p2.tableoid = t.tbl
LEFT   JOIN pa456889 p3 ON p3.cpa = t.cpa AND p3.tableoid = t.tbl

For mange borde

Kombiner en loop med dynamiske forespørgsler:

CREATE OR REPLACE FUNCTION foo(_number int)
  RETURNS TABLE (cpa int, nr text, vym text) AS
$func$
DECLARE
   _nr text;
BEGIN
FOR _nr IN
   SELECT DISTINCT substring(ku,'[0-9]+')
   FROM   public."table_data_C"
LOOP
   RETURN QUERY EXECUTE format(
      'SELECT t.cpa, _nr, p.vym 
       FROM   public."table_data_C" t
       LEFT   JOIN %I p USING (cpa)
       WHERE  t.ku LIKE (_nr || '%')'
     , 'pa' || _nr
     );
END LOOP;

END
$func$ LANGUAGE plpgsql;



  1. Oracle SQL-privilegieautorisation på flere attributter og tabeller med én sætning

  2. Tilslutning af Excel til PostgreSQL via VBA

  3. at oprette forbindelse til en docker-compose mysql-beholder nægter adgang, men docker, der kører det samme billede, gør det ikke

  4. Nulstil sekvens i jpa