Sql 将所有查询与具有不同列数的查询合并
我遇到过这样一个例子,我期望返回一个错误的sqlite查询实际上是成功的,我想知道是否有人能指出为什么这个查询是有效的Sql 将所有查询与具有不同列数的查询合并,sql,sqlite,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
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*
则会收到预期的错误:并集左侧和右侧的选择都没有相同数量的结果列
答案似乎很简单:是的,这是一个怪癖。
我想用一个简短的例子来说明这一点。但在此之前,让我们先咨询一下:
两个或多个简单的SELECT语句可以连接在一起形成
使用“并集”、“全部并集”、“相交”或“除外”进行复合选择
操作人员
在复合选择中,所有成分选择都必须
返回相同数量的结果列
因此,文档非常清楚地指出,两个选项必须提供相同数量的列。然而,正如您所说,最外层的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没有忽略该列,而是添加了一个空值
结论
这使我得出结论,如果将sqlite作为子查询处理,它只需以不同的方式处理UNION ALL
PS:如果您只是使用UNION
它在任何情况下都会失败。UNION ALL将在额外的列中返回带有空值的结果
基本联合将失败,因为没有ALL的联合必须具有来自两个表的相同列数
因此:
返回第3列中有空值的3列
以及:
应失败,因为列数不匹配
总之,您可以向UNION中添加一个空白列,这样您就可以从每个表中选择3列,并且它仍然可以工作
例:
如果第二个查询的列数较少,则可以执行以下操作:
select col1, col2, col3, col4, col5
from table A
union all
select col1, col2, col3, col4, NULL as col5,
from table B
除了NULL
,还可以使用一些字符串常量-'KPI',因为col5
看起来像SQLite中的一个怪癖!奇怪-它会返回什么?缺少的列为空?哦,我检查了演示,它忽略了该列。@Michael:它返回的rowid和k没有任何第三列。为什么查询无效?这个答案似乎不是UNION vs UNION ALL的准确描述。基于此,UNION和UNION都是相同的,只是UNION还对结果执行SELECT DISTINCT。它与列无关Sunion ALL不接受不同的列计数。
SELECT column1, column2 FROM table a
UNION
SELECT column1, column2, column3 FROM table b
SELECT column1, column2, '' AS column3 FROM table a
UNION
SELECT column1, column2, column3 FROM table b
select col1, col2, col3, col4, col5
from table A
union all
select col1, col2, col3, col4, NULL as col5,
from table B