sql - 联合所有具有不同列数的查询

标签 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
  )
)

sqlfiddle of above

我认为联合两个具有不同列数的选择会返回错误。如果我删除最外层的 SELECT *,则会收到我预期的错误:UNION ALL 左侧和右侧的 SELECT 没有相同数量的结果列

最佳答案

这个问题的答案似乎很简单:是的,这是一个怪癖。 我想用一个简短的例子来证明这一点。但在此之前,让我们咨询一下 documentation :

Two or more simple SELECT statements may be connected together to form a compound SELECT using the UNION, UNION ALL, INTERSECT or EXCEPT operator. In a compound SELECT, all the constituent SELECTs must return the same number of result columns.

因此文档非常清楚地说明两个 SELECTs 必须提供相同数量的列。但是,正如您所说,最外面的 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 被简单地省略了。

示例 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 不会省略该列,而是添加一个空值。

结论

这让我得出结论,如果将 UNION ALL 作为子查询处理,则 sqlite 只是简单地以不同方式处理它。

PS:如果您只是使用 UNION,它在任何情况下都会失败。

关于sql - 联合所有具有不同列数的查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11704450/

相关文章:

java - 如何在另一个类中为 SQLite 数据库管理类使用 get 方法?

go - 使用事务进行 sqlite 查询?

c# - log4net 和 system.data.sqlite

sql - * 和显式字段列表的结果不同?

mysql - 操作数应包含 1 列或语法错误

sql - 非常复杂的数据库架构,如何处理呢?

python - Google bigQuery 拆分列

mysql 似乎不适用于我的新 Rails 应用程序

mysql - sql中如何计算两个不同的列

php - mysql_fetch_assoc 不返回任何内容(不是 null、不是 0、不是 "")