7

私はクエリシステムを実装していました。アンネスト機能を実装しました。現在、ユーザーは単一の select ステートメントで複数の unnest を使用することについて尋ねていました。ほとんどのユーザーがクエリ システムの前に PostgreSQL を使用していたため、一種のガイドラインとして PostgreSQL を使用していました。

PostgreSQL には次のような奇妙な動作があります。

postgres=# select unnest(array[1,2]), unnest(array[1,2]);
 unnest | unnest
--------+--------
      1 |      1
      2 |      2
(2 rows)

postgres=# select unnest(array[1,2]), unnest(array[1,2,3]);
 unnest | unnest
--------+--------
      1 |      1
      2 |      2
      1 |      3
      2 |      1
      1 |      2
      2 |      3
(6 rows)

私の実装は常にデカルト積として生成されました。私は疑問に思っています、これの背後にある正しいロジックは何ですか? PostgreSQL は正しいことをしているのですか、それとも単なるバグですか? ANSI ドキュメントや PostgreSQL ドキュメントに明確な説明が見つかりませんでした。

4

1 に答える 1

9

これは unnest そのものに関するものではなく、SELECTリスト内の複数のセットを返す関数に対する PostgreSQL の非常に奇妙な処理に関するものです。のセットを返す関数SELECTは、ANSI SQL 標準の一部ではありません。

可能な限りLATERAL集合を返す関数を使用するよりも、クエリを使用した方がより適切な動作であることがわかります。FROM

select a, b FROM unnest(array[1,2]) a, LATERAL unnest(array[1,2,3]) b;

例えば

regress=> select a, b FROM unnest(array[1,2]) a, LATERAL unnest(array[1,2,3]) b;
 a | b 
---+---
 1 | 1
 1 | 2
 1 | 3
 2 | 1
 2 | 2
 2 | 3
(6 rows)

私がまだ複数のセットを返す関数を使用してSELECTいるのは、両方とも同じ行数を返す関数の値をペアにしたいときだけです。その必要性は、9.4 でなくなり、複数の引数unnestWITH ORDINALITY.

于 2014-04-11T05:24:47.593 に答える