将all与具有不同列数的查询联合起来

use*_*123 11 sql sqlite

我遇到一个案例,我希望返回错误的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
  )
)
Run Code Online (Sandbox Code Playgroud)

上面的方块

我认为联合两个具有不同列数的选择将返回错误.如果我移除最外层,SELECT *那么我会收到我期待的错误:SELECTs to the left and right of UNION ALL do not have the same number of result columns.

Seb*_*jas 11

答案似乎很简单:是的,这是一个怪癖. 我想用一个简短的例子来证明这一点.但是事先,请查阅文档:

可以使用UNION,UNION ALL,INTERSECT或EXCEPT运算符将两个或多个简单SELECT语句连接在一起以形成复合SELECT.在复合SELECT中,所有组成SELECT必须返回相同数量的结果列.

因此,文件非常清楚地说明两个SELECTs必须提供相同数量的列.然而,正如你所说,最外面的SELECT奇怪地避免了这种"限制".

例1

SELECT * FROM(
    SELECT k, v FROM test_table
  UNION ALL
    SELECT k, v,rowid FROM test_table
);
Run Code Online (Sandbox Code Playgroud)

结果:

k|v
4|5
4|5
Run Code Online (Sandbox Code Playgroud)

rowid评论中所指出的,第三列被简单地省略.

例2

我们只是切换两个select语句的顺序.

 SELECT * FROM(
    SELECT k, v, rowid FROM test_table
  UNION ALL
     SELECT k, v FROM test_table
  );
Run Code Online (Sandbox Code Playgroud)

结果

k|v|rowid
4|5|1
4|5|
Run Code Online (Sandbox Code Playgroud)

现在,sqlite不会省略列但添加空值.

结论

这让我得出结论,如果sqlite UNION ALL作为子查询处理,它只是处理不同.

PS:如果您只是UNION在任何情况下使用它失败.


小智 9

UNION ALL将在额外列中返回带有空值的结果.

基本UNION将失败,因为没有ALL的UNION必须具有来自两个表的相同列数.

所以:

SELECT column1, column2 FROM table a
UNION ALL 
SELECT column1, column2, column3 FROM table b
Run Code Online (Sandbox Code Playgroud)

返回3列中带有空值的3列.

和:

SELECT column1, column2 FROM table a
UNION 
SELECT column1, column2, column3 FROM table b
Run Code Online (Sandbox Code Playgroud)

应该失败,因为列数不匹配.

总之,您可以向UNION添加一个空白列,以便从每个表中选择3列,它仍然可以工作.

EX:

SELECT column1, column2, '' AS column3 FROM table a
UNION  
SELECT column1, column2, column3 FROM table b
Run Code Online (Sandbox Code Playgroud)

  • 这个答案似乎并不是 UNION 与 UNION ALL 的准确描述。基于此/sf/ask/3494781/ Between-union-and-union-all,UNION和UNION ALL是相同的,除了UNION还在结果。和列没有关系 (2认同)