热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

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

IverunintoacasewhereasqlitequeryImexpectingtoreturnanerrorisactuallysucceedingan

I've run into a case where a sqlite query I'm expecting to return an error is actually succeeding and I was wondering if anyone could point out why this query is valid.

我遇到一个案例,我希望返回错误的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

上面的方块

I would think that unioning two selects which have a different number of columns would return an error. If I remove the outermost SELECT * then I receive the error I'm expecting: SELECTs to the left and right of UNION ALL do not have the same number of result columns.

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

2 个解决方案

#1


10  

The answer to this seems to be straightforward: Yes, this is a quirk. I'd like to demonstrate this with a short example. But beforehand, let's consult the 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.

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

So the documentations says very clearly that two SELECTs must provide the same number of columns. However, as you said, the outermost SELECT strangely avoids this 'limitation'.

因此,文档非常清楚地说明两个SELECT必须提供相同数量的列。但是,正如你所说,最外面的SELECT奇怪地避免了这种“限制”。

Example 1

例1

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

Result:

结果:

k|v
4|5
4|5

The third column rowid gets simply omitted, as pointed out in the comments.

正如评论中所指出的那样,第三列rowid被简单地省略了。

Example 2

例2

We are only switching the order of the two select statements.

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

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

Result

结果

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

Now, sqlite does not omit the column but add a null value.

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

Conclusion

结论

This brings me to my conclusion, that sqlite simply handles the UNION ALL differently if it is processed as a subquery.

这让我得出结论,如果将sqlite作为子查询处理,它将简单地处理UNION ALL。

PS: If you are just using UNION it fails at any scenario.

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

#2


8  

UNION ALL will return the results with null values in the extra columns.

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

A basic UNION will fail because UNION without the ALL has to have the same number of columns from both tables.

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

So:

所以:

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

returns 3 columns with nulls in column 3.

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

and:

和:

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

should fail because the number of columns do not match.

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

In conclusion you could add a blank column to the UNION so that you are selecting 3 columns from each table and it would still work.

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

EX:

EX:

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

推荐阅读
  • ALTERTABLE通过更改、添加、除去列和约束,或者通过启用或禁用约束和触发器来更改表的定义。语法ALTERTABLEtable{[ALTERCOLUMNcolu ... [详细]
  • WhenImtryingtorunthefollowing:当我试图运行以下内容时:ContentValuescvnewContentValues();cv ... [详细]
  • 本文详细介绍了Spring的JdbcTemplate的使用方法,包括执行存储过程、存储函数的call()方法,执行任何SQL语句的execute()方法,单个更新和批量更新的update()和batchUpdate()方法,以及单查和列表查询的query()和queryForXXX()方法。提供了经过测试的API供使用。 ... [详细]
  • MyBatis多表查询与动态SQL使用
    本文介绍了MyBatis多表查询与动态SQL的使用方法,包括一对一查询和一对多查询。同时还介绍了动态SQL的使用,包括if标签、trim标签、where标签、set标签和foreach标签的用法。文章还提供了相关的配置信息和示例代码。 ... [详细]
  • 在Oracle11g以前版本中的的DataGuard物理备用数据库,可以以只读的方式打开数据库,但此时MediaRecovery利用日志进行数据同步的过 ... [详细]
  • Explain如何助力SQL语句的优化及其分析方法
    本文介绍了Explain如何助力SQL语句的优化以及分析方法。Explain是一个数据库SQL语句的模拟器,通过对SQL语句的模拟返回一个性能分析表,从而帮助工程师了解程序运行缓慢的原因。文章还介绍了Explain运行方法以及如何分析Explain表格中各个字段的含义。MySQL 5.5开始支持Explain功能,但仅限于select语句,而MySQL 5.7逐渐支持对update、delete和insert语句的模拟和分析。 ... [详细]
  • 十大经典排序算法动图演示+Python实现
    本文介绍了十大经典排序算法的原理、演示和Python实现。排序算法分为内部排序和外部排序,常见的内部排序算法有插入排序、希尔排序、选择排序、冒泡排序、归并排序、快速排序、堆排序、基数排序等。文章还解释了时间复杂度和稳定性的概念,并提供了相关的名词解释。 ... [详细]
  • 我正在一个涉及SQLite的项目中,我只有一个数据库文件,现在我正在测试我的应 ... [详细]
  • 在Android Studio中查看SQLite数据库
    原来查看数据库内容,我们一般都是将数据库文件从手机导出,再用专门的软件打开查看,比较繁琐。最近发现了一个比较方便的方法:使用工具stetho。使用方式在gradle中配置depen ... [详细]
  • 电话号码的字母组合解题思路和代码示例
    本文介绍了力扣题目《电话号码的字母组合》的解题思路和代码示例。通过使用哈希表和递归求解的方法,可以将给定的电话号码转换为对应的字母组合。详细的解题思路和代码示例可以帮助读者更好地理解和实现该题目。 ... [详细]
  • 向QTextEdit拖放文件的方法及实现步骤
    本文介绍了在使用QTextEdit时如何实现拖放文件的功能,包括相关的方法和实现步骤。通过重写dragEnterEvent和dropEvent函数,并结合QMimeData和QUrl等类,可以轻松实现向QTextEdit拖放文件的功能。详细的代码实现和说明可以参考本文提供的示例代码。 ... [详细]
  • 本文讨论了一个关于cuowu类的问题,作者在使用cuowu类时遇到了错误提示和使用AdjustmentListener的问题。文章提供了16个解决方案,并给出了两个可能导致错误的原因。 ... [详细]
  • 本文介绍了UVALive6575题目Odd and Even Zeroes的解法,使用了数位dp和找规律的方法。阶乘的定义和性质被介绍,并给出了一些例子。其中,部分阶乘的尾零个数为奇数,部分为偶数。 ... [详细]
  • IjustinheritedsomewebpageswhichusesMooTools.IneverusedMooTools.NowIneedtoaddsomef ... [详细]
  • SQLite–CONSTRAINTS(约束)约束是数据列在表上执行的规则。这些是用来限制的数据类型可以进入一个表。这样可以确保数据的准确性和可靠性在数据库中。    级或表级约束可 ... [详细]
author-avatar
s350350350
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有