我遇到过一个情况,我期望返回错误的 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
)
)
我认为联合两个具有不同列数的选择会返回错误。如果我删除最外层的 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/