热门标签 | 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

推荐阅读
  • 利用python爬取豆瓣电影Top250的相关信息,包括电影详情链接,图片链接,影片中文名,影片外国名,评分,评价数,概况,导演,主演,年份,地区,类别这12项内容,然后将爬取的信息写入Exce ... [详细]
  • Ihavetwomethodsofgeneratingmdistinctrandomnumbersintherange[0..n-1]我有两种方法在范围[0.n-1]中生 ... [详细]
  • 在Delphi7下要制作系统托盘,只能制作一个比较简单的系统托盘,因为ShellAPI文件定义的TNotifyIconData结构体是比较早的版本。定义如下:1234 ... [详细]
  • poj 3352 Road Construction ... [详细]
  • 本文详细介绍了MySQL数据库的基础语法与核心操作,涵盖从基础概念到具体应用的多个方面。首先,文章从基础知识入手,逐步深入到创建和修改数据表的操作。接着,详细讲解了如何进行数据的插入、更新与删除。在查询部分,不仅介绍了DISTINCT和LIMIT的使用方法,还探讨了排序、过滤和通配符的应用。此外,文章还涵盖了计算字段以及多种函数的使用,包括文本处理、日期和时间处理及数值处理等。通过这些内容,读者可以全面掌握MySQL数据库的核心操作技巧。 ... [详细]
  • 本文介绍了如何利用 `matplotlib` 库中的 `FuncAnimation` 类将 Python 中的动态图像保存为视频文件。通过详细解释 `FuncAnimation` 类的参数和方法,文章提供了多种实用技巧,帮助用户高效地生成高质量的动态图像视频。此外,还探讨了不同视频编码器的选择及其对输出文件质量的影响,为读者提供了全面的技术指导。 ... [详细]
  • 在尝试对 QQmlPropertyMap 类进行测试驱动开发时,发现其派生类中无法正常调用槽函数或 Q_INVOKABLE 方法。这可能是由于 QQmlPropertyMap 的内部实现机制导致的,需要进一步研究以找到解决方案。 ... [详细]
  • 在HTML布局中,即使将 `top: 0%` 和 `left: 0%` 设置为元素的定位属性,浏览器中仍然会出现空白填充。这个问题通常与默认的浏览器样式、盒模型或父元素的定位方式有关。为了消除这些空白,可以考虑重置浏览器的默认样式,确保父元素的定位方式正确,并检查是否有其他CSS规则影响了元素的位置。 ... [详细]
  • Android 构建基础流程详解
    Android 构建基础流程详解 ... [详细]
  • 本文介绍了如何利用Shell脚本高效地部署MHA(MySQL High Availability)高可用集群。通过详细的脚本编写和配置示例,展示了自动化部署过程中的关键步骤和注意事项。该方法不仅简化了集群的部署流程,还提高了系统的稳定性和可用性。 ... [详细]
  • 本文详细解析了 Android 系统启动过程中的核心文件 `init.c`,探讨了其在系统初始化阶段的关键作用。通过对 `init.c` 的源代码进行深入分析,揭示了其如何管理进程、解析配置文件以及执行系统启动脚本。此外,文章还介绍了 `init` 进程的生命周期及其与内核的交互方式,为开发者提供了深入了解 Android 启动机制的宝贵资料。 ... [详细]
  • 在PHP中,高效地分割字符串是一项常见的需求。本文探讨了多种技术,用于在特定字符(如“或”)后进行字符串分割。通过使用正则表达式和内置函数,可以实现更加灵活和高效的字符串处理。例如,可以使用 `preg_split` 函数来实现这一目标,该函数允许指定复杂的分隔符模式,从而提高代码的可读性和性能。此外,文章还介绍了如何优化分割操作以减少内存消耗和提高执行速度。 ... [详细]
  • 当使用 `new` 表达式(即通过 `new` 动态创建对象)时,会发生两件事:首先,内存被分配用于存储新对象;其次,该对象的构造函数被调用以初始化对象。为了确保资源管理的一致性和避免内存泄漏,建议在使用 `new` 和 `delete` 时保持形式一致。例如,如果使用 `new[]` 分配数组,则应使用 `delete[]` 来释放内存;同样,如果使用 `new` 分配单个对象,则应使用 `delete` 来释放内存。这种一致性有助于防止常见的编程错误,提高代码的健壮性和可维护性。 ... [详细]
  • 题目要求维护一个数列,并支持两种操作:一是查询操作,语法为QL,用于查询数列末尾L个数中的最大值;二是更新操作,用于修改数列中的某个元素。本文通过ST表(Sparse Table)优化查询效率,确保在O(1)时间内完成查询,同时保持较低的预处理时间复杂度。 ... [详细]
  • 深入理解排序算法:集合 1(编程语言中的高效排序工具) ... [详细]
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社区 版权所有