12

エラーを返すと予想される sqlite クエリが実際に成功しているケースに遭遇しました。このクエリが有効である理由を誰かが指摘できるかどうか疑問に思っていました。

CREATE TABLE test_table(
  k INTEGER,
  v INTEGER
);

INSERT INTO test_table( k, v ) VALUES( 4, 5 );

SELECT * FROM(
  SELECT * FROM(
    SELECT k, v FROM test_table WHERE 1 = 0
  )
  UNION ALL
  SELECT * FROM(
    SELECT rowid, k, v FROM test_table
  )
)

上記のsqlfiddle

列数が異なる2つの選択を結合するとエラーが返されると思います。最も外側のものを削除するとSELECT *、エラーが発生しますSELECTs to the left and right of UNION ALL do not have the same number of result columns

4

3 に答える 3

11

これに対する答えは簡単に思えます:はい、これは癖です。 これを短い例で示したいと思います。ただし、事前にドキュメントを参照してください。

UNION、UNION ALL、INTERSECT、または EXCEPT 演算子を使用して、2 つ以上の単純な SELECT ステートメントを結合して、複合 SELECT を形成することができます。複合 SELECT では、すべての構成要素の SELECT が同じ数の結果列を返す必要があります。

SELECTsしたがって、ドキュメンテーションには、2 つが同じ数の列を提供する必要があることが非常に明確に示されています。しかし、おっしゃる通り、最外部はSELECT奇妙にこの「制限」を回避しています。

例 1

SELECT * FROM(
    SELECT k, v FROM test_table
  UNION ALL
    SELECT k, v,rowid FROM test_table
);

結果:

k|v
4|5
4|5

rowidコメントで指摘されているように、3 番目の列は単純に省略されます。

例 2

2 つの select ステートメントの順序を入れ替えているだけです。

 SELECT * FROM(
    SELECT k, v, rowid FROM test_table
  UNION ALL
     SELECT k, v FROM test_table
  );

結果

k|v|rowid
4|5|1
4|5|

現在、sqlite は列を省略せず、null 値を追加しています。

結論

UNION ALLこれは、サブクエリとして処理される場合、sqlite は単純に別の方法で処理するという私の結論に至ります。

PS: 使用しているだけのUNION場合、どのシナリオでも失敗します。

于 2012-07-31T15:28:07.067 に答える
10

UNION ALLは、追加の列にnull値を含む結果を返します。

ALLのないUNIONは、両方のテーブルの同じ数の列を持っている必要があるため、基本的なUNIONは失敗します。

それで:

SELECT column1, column2 FROM table a
UNION ALL 
SELECT column1, column2, column3 FROM table b

列3にNULLを含む3列を返します。

と:

SELECT column1, column2 FROM table a
UNION 
SELECT column1, column2, column3 FROM table b

列の数が一致しないため、失敗するはずです。

結論として、UNIONに空白の列を追加して、各テーブルから3つの列を選択しても、引き続き機能するようにすることができます。

元:

SELECT column1, column2, '' AS column3 FROM table a
UNION  
SELECT column1, column2, column3 FROM table b
于 2012-08-08T03:17:35.863 に答える