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

関数から返されたレコードには、列が連結されています

    通常、行を分解する 関数から返され、個々の列を取得します:

    SELECT * FROM account_servicetier_for_day(20424, '2014-08-12');

    クエリについて:

    Postgres9.3以降

    JOIN LATERALを使用したクリーナー :

    SELECT '2014-08-12' AS day, 0 AS inbytes, 0 AS outbytes
         , a.username, a.accountid, a.userid
         , f.*   -- but avoid duplicate column names!
    FROM   account_tab a
         , account_servicetier_for_day(a.accountid, '2014-08-12') f  -- <-- HERE
    WHERE  a.isdsl = 1
    AND    a.dslservicetypeid IS NOT NULL
    AND    NOT EXISTS (
       SELECT 1
       FROM   dailyaccounting_tab
       WHERE  day = '2014-08-12'
       AND    accountid = a.accountid
       )
    ORDER  BY a.username;
    

    LATERAL キーワードはここでは暗黙的であり、関数は常に以前のFROMを参照できます アイテム。マニュアル:

    LATERAL 関数呼び出しの前にFROMを付けることもできます アイテムですが、関数式は以前のFROMを参照できるため、この場合はノイズワードです。 いずれにせよアイテム。

    関連:

    • 別のテーブルの番号に基づいて、1つのテーブルに複数の行を挿入します

    FROMにコンマを含む短い表記 リストは(ほとんど)CROSS JOIN LATERALと同等です ([INNER] JOIN LATERAL ... ON TRUEと同じです )したがって、関数呼び出しが行を返さない結果から行を削除します。このような行を保持するには、 LEFT JOIN LATERAL ... ON TRUEを使用します。

    ...
    FROM  account_tab a
    LEFT  JOIN LATERAL account_servicetier_for_day(a.accountid, '2014-08-12') f ON TRUE
    ...
    

    また、NOT IN (subquery)は使用しないでください あなたがそれを避けることができるとき。これを行うには、いくつかの方法の中で最も遅く、最も注意が必要です。

    • 他のテーブルに存在しない行を選択します

    NOT EXISTSをお勧めします 代わりに。

    Postgres9.2以前

    SELECTでセットを返す関数を呼び出すことができます リスト(これは標準SQLのPostgres拡張です)。パフォーマンス上の理由から、これはサブクエリで行うのが最適です。関数の繰り返しの評価を避けるために、外部クエリの(よく知られている!)行タイプを分解します。

    SELECT '2014-08-12' AS day, 0 AS inbytes, 0 AS outbytes
         , a.username, a.accountid, a.userid
         , (a.rec).*   -- but avoid duplicate column names!
    FROM  (
       SELECT *, account_servicetier_for_day(a.accountid, '2014-08-12') AS rec
       FROM   account_tab a
       WHERE  a.isdsl = 1
       AND    a.dslservicetypeid Is Not Null
       AND    NOT EXISTS (
           SELECT 1
           FROM   dailyaccounting_tab
           WHERE  day = '2014-08-12'
           AND    accountid = a.accountid
          )
       ) a
    ORDER  BY a.username;
    

    Craig Ringerによる関連する回答と説明、外部クエリで分解する方がよい理由:

    • SQLクエリで(func())。*構文を使用して複数の関数の評価を回避するにはどうすればよいですか?

    Postgres 10 SELECTのセットを返す関数の動作の奇妙な点を削除しました :

    • SELECT句で複数のセットを返す関数に期待される動作は何ですか?


    1. Oracle:blobを含むテーブルを.sqlファイルにエクスポートして、再度インポートできるようにします。

    2. ダブルクエリなしのMySQLページネーション?

    3. アマゾンウェブサービス(AWS)の自動スケーリングの概要

    4. Amazon EC2、InnoDB:mmap(xバイト)が失敗したため、mysqlが開始を中止しました。 errno 12