Postgres10以降
小さいセットにはnull値を追加します。 generate_series()
を使用したデモ :
SELECT generate_series( 1, 2) AS row2
, generate_series(11, 13) AS row3
, generate_series(21, 24) AS row4;
row2 | row3 | row4 -----+------+----- 1 | 11 | 21 2 | 12 | 22 null | 13 | 23 null | null | 24
ここにdbfiddle
Postgres 10のマニュアル :
クエリの選択リストに複数のセットを返す関数がある場合、動作は、関数を単一の
LATERAL ROWS FROM( ... )
に配置した場合と同様になります。FROM
-条項項目。基になるクエリの各行には、各関数の最初の結果を使用する出力行があり、次に2番目の結果を使用する出力行があります。一部のset-returning関数が他の関数よりも少ない出力を生成する場合、欠落データの代わりにnull値が使用されるため、1つの基になる行に対して出力される行の総数は、最も多くの出力を生成したset-returning関数の場合と同じになります。したがって、セットを返す関数は、すべてが使い果たされるまで「ロックステップで」実行され、その後、実行は次の基になる行から続行されます。
これにより、従来の奇妙な動作が終了します。
Postgres9.6以前
結果の行数(やや意外なことに!)は、最小公倍数です。 同じSELECT
内のすべてのセットの リスト。 (CROSS JOIN
のようにのみ機能します すべてのセットサイズに共通の除数がない場合!)デモ:
SELECT generate_series( 1, 2) AS row2
, generate_series(11, 13) AS row3
, generate_series(21, 24) AS row4;
row2 | row3 | row4 -----+------+----- 1 | 11 | 21 2 | 12 | 22 1 | 13 | 23 2 | 11 | 24 1 | 12 | 21 2 | 13 | 22 1 | 11 | 23 2 | 12 | 24 1 | 13 | 21 2 | 11 | 22 1 | 12 | 23 2 | 13 | 24
ここにdbfiddle
Postgres 9.6のマニュアルに記載されています 「セットを返すSQL関数」の章 、それを回避するための推奨事項とともに:
注:
FROM
ではなく、選択リストでset-returning関数を使用する場合の主な問題 節は、同じ選択リストに複数のセットを返す関数を入れても、あまり意味のない動作をしないということです。 (そうすると実際に得られるのは、各セットを返す関数によって生成される行数の最小公倍数に等しい出力行数です。 )LATERAL
構文は、複数の集合を返す関数を呼び出すときに驚くべき結果を生み出さないため、通常は代わりに使用する必要があります。
大胆な強調鉱山。
単一のセットを返す関数はOKです(ただし、FROM
ではさらにクリーンです リスト)、ただし同じSELECT
に複数 リストは現在お勧めできません。これは、LATERAL
が登場する前は便利な機能でした。 参加します。今では単なる歴史的なバラストです。
関連:
- PostgreSQLでの並列unnest()と並べ替え順序
- 複数のアレイを並列にネスト解除する
- LATERAL JOINとPostgreSQLのサブクエリの違いは何ですか?