sql >> データベース >  >> RDS >> PostgreSQL

複合型を返すPostgreSQL関数から選択します

    Postgres9.3以降

    LATERAL 参加してください!

    SELECT p.id, p.name, p.data, f.*
    FROM   tb_projects p
    LEFT   JOIN LATERAL fn_getlinkedproject(p.id) f(linked_id, lined_name) ON TRUE;
    

    結果:

     id |  data  |  name  | linked_id | linked_name
    ----+--------+--------+-----------+-------------
      1 | data_1 | name_1 |         2 | name_2
      2 | data_2 | name_2 |         3 | name_3
      3 | data_3 | name_3 |         1 | name_1
    

    参照:

    Postgres9.2以前

    いくつかの理由で劣っています。列エイリアスの添付はそれほど簡単ではありません。むしろ、他の競合する名前の名前を変更します:

    SELECT p.id AS p_id, p.data AS p_data, p.name AS p_name, (fn_getlinkedproject(p.id)).*
    FROM   tb_projects p;
    

    結果:

     p_id | p_data | p_name | id |  name
    ------+--------+--------+----+--------
        1 | data_1 | name_1 |  2 | name_2
        2 | data_2 | name_2 |  3 | name_3
        3 | data_3 | name_3 |  1 | name_1
    

    名前を変更する 結果の列には、次のことを行う必要があります。

    SELECT p.id, p.data, p.name
         ,(fn_getlinkedproject(p.id)).id   AS linked_id
         ,(fn_getlinkedproject(p.id)).name AS linked_name
    FROM   tb_projects p;
    

    どちらの古いソリューションも、関数を繰り返し呼び出すという同じ(不十分な)クエリプランに解決されます。

    これを回避するには、サブクエリを使用します:

    SELECT p.id, p.data, p.name
        , (p.x).id AS linked_id, (p.x).name AS linked_name
    FROM  (SELECT *, fn_getlinkedproject(id) AS x FROM tb_projects) p;
    

    重要な括弧の配置に注意してください 。
    複合型に関するマニュアル をお読みください 。

    デモ

    CREATE TYPE dm_nameid AS (
      id   int
    , name text); -- types simplified for demo
    
    CREATE TABLE tb_projects(
      id   int
    , data text
    , name text);
    
    INSERT INTO tb_projects VALUES
      (1, 'data_1', 'name_1')
    , (2, 'data_2', 'name_2')
    , (3, 'data_3', 'name_3');
    
    CREATE function fn_getlinkedproject(integer)  -- avoiding CaMeL-case for demo
      RETURNS dm_nameid LANGUAGE sql AS
    'SELECT id, name FROM tb_projects WHERE id = ($1 % 3) + 1';
    

    db <> fiddle こちら




    1. MySQLで一括挿入を行う方法は?

    2. jsonでエンコードされたデータをmysqlに挿入する

    3. PL/pgSQLを使用してPostgreSQLのレコードとして複数のフィールドを返します

    4. Javaを使用したデータベース内の英語以外の文字