通常、行を分解する 関数から返され、個々の列を取得します:
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句で複数のセットを返す関数に期待される動作は何ですか?