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

Levé spojení s názvem dynamické tabulky odvozeným ze sloupce

V každém případě potřebujete dynamické SQL.

Název tabulky jako daný parametr

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;

Volejte:

SELECT * FROM foo(456887)

Obecně byste názvy tabulek dezinfikovali pomocí format ( %I ) abyste se vyhnuli SQL injection. Pouze s integer jako dynamický vstup, který není nutný. Další podrobnosti a odkazy v této související odpovědi:
INSERT s názvem dynamické tabulky ve funkci spouštění

Datový model

Datový model může mít dobré důvody. Jako rozdělení/sharding nebo samostatná oprávnění...
Pokud nemáte tak dobrý důvod, zvažte konsolidaci více tabulek se stejným schématem do jedné a přidejte number jako sloupec. Pak nepotřebujete dynamické SQL.

Zvažte dědění . Potom můžete přidat podmínku na tableoid načíst pouze řádky z dané podřízené tabulky:

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

Uvědomte si však omezení dědičnosti. Související odpovědi:

Název 2. tabulky v závislosti na hodnotě v 1. tabulce

Odvozování názvu spojovací tabulky z hodnot v první tabulce věci dynamicky komplikuje.

Pouze pro několik stolů

LEFT JOIN každý na tableoid . Na každý řádek existuje pouze jedna shoda, proto použijte 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

Pro mnoho tabulek

Zkombinujte smyčku s dynamickými dotazy:

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. Jak se připojit k mssql pomocí pdo přes PHP a Linux?

  2. Funkce s proměnným počtem vstupních parametrů

  3. Jak zkontrolovat zastaralé statistiky

  4. Vraťte řádky, které obsahují alfanumerické znaky v SQLite