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

为什么选择0,而不是选择-WhySELECT0,…insteadofSELECT

LetssayIhaveaSQLitedatabasethatcontainsatable:假设我有一个SQLite数据库,其中包含一个表:sqlite>create

Lets say I have a SQLite database that contains a table:

假设我有一个SQLite数据库,其中包含一个表:

sqlite> create table person (id integer, firstname varchar, lastname varchar);

Now I want to get every entry which is in the table.

现在我想要得到表格中的每一个元素。

sqlite> select t0.id, t0.firstname, t0.lastname from person t0;

This works fine and this it what I would use. However I have worked with a framework from Apple (Core Data) that generates SQL. This framework generates a slightly different SQL query:

这很好,这就是我要用的。然而,我使用了一个来自苹果的框架(核心数据)来生成SQL。这个框架生成的SQL查询稍有不同:

sqlite> select 0, t0.id, t0.firstname, t0.lastname from person t0;

Every SQL query generated by this framework begins with "select 0,". Why is that?

这个框架生成的每个SQL查询都以“select 0”开头。这是为什么呢?

I tried to use the explain command to see whats going on but this was inconclusive - at least to me.

我试着使用explain命令来查看发生了什么,但这是不确定的——至少对我来说是这样。

sqlite> explain select t0.id, t0.firstname, t0.lastname from person t0;
addr        opcode      p1          p2          p3          p4          p5          comment   
----------  ----------  ----------  ----------  ----------  ----------  ----------  ----------
0           Trace       0           0           0                       00          NULL      
1           Goto        0           11          0                       00          NULL      
2           OpenRead    0           2           0           3           00          NULL      
3           Rewind      0           9           0                       00          NULL      
4           Column      0           0           1                       00          NULL      
5           Column      0           1           2                       00          NULL      
6           Column      0           2           3                       00          NULL      
7           ResultRow   1           3           0                       00          NULL      
8           Next        0           4           0                       01          NULL      
9           Close       0           0           0                       00          NULL      
10          Halt        0           0           0                       00          NULL      
11          Transactio  0           0           0                       00          NULL      
12          VerifyCook  0           1           0                       00          NULL      
13          TableLock   0           2           0           person      00          NULL      
14          Goto        0           2           0                       00          NULL 

And the table for the second query looks like this:

第二个查询的表格是这样的:

sqlite> explain select 0, t0.id, t0.firstname, t0.lastname from person t0;
addr        opcode      p1          p2          p3          p4          p5          comment   
----------  ----------  ----------  ----------  ----------  ----------  ----------  ----------
0           Trace       0           0           0                       00          NULL      
1           Goto        0           12          0                       00          NULL      
2           OpenRead    0           2           0           3           00          NULL      
3           Rewind      0           10          0                       00          NULL      
4           Integer     0           1           0                       00          NULL      
5           Column      0           0           2                       00          NULL      
6           Column      0           1           3                       00          NULL      
7           Column      0           2           4                       00          NULL      
8           ResultRow   1           4           0                       00          NULL      
9           Next        0           4           0                       01          NULL      
10          Close       0           0           0                       00          NULL      
11          Halt        0           0           0                       00          NULL      
12          Transactio  0           0           0                       00          NULL      
13          VerifyCook  0           1           0                       00          NULL      
14          TableLock   0           2           0           person      00          NULL      
15          Goto        0           2           0                       00          NULL     

3 个解决方案

#1


15  

Some frameworks do this in order to tell, without any doubt, whether a row from that table was returned.

有些框架这样做是为了告诉,毫无疑问,是否返回了该表中的一行。

Consider

考虑

  A      B
+---+  +---+------+
| a |  | a | b    |
+---+  +---+------+
| 0 |  | 0 |    1 |
+---+  +---+------+
| 1 |  | 1 | NULL |
+---+  +---+------+
| 2 |
+---+

SELECT A.a, B.b
FROM A
LEFT JOIN B
ON B.a = A.a

  Results
+---+------+
| a | b    |
+---+------+
| 0 |    1 |
+---+------+
| 1 | NULL |
+---+------+
| 2 | NULL |
+---+------+

In this result set, it is not possible to see that a = 1 exists in table B, but a = 2 does not. To get that information, you need to select a non-nullable expression from table b, and the simplest way to do that is to select a simple constant value.

在这个结果集中,不可能在表B中看到a = 1,但是a = 2不存在。要获取这些信息,需要从表b中选择一个非空表达式,最简单的方法是选择一个简单的常量值。

SELECT A.a, B.x, B.b
FROM A
LEFT JOIN (SELECT 0 AS x, B.a, B.b FROM B) AS B
ON B.a = A.a

  Results
+---+------+------+
| a | x    | b    |
+---+------+------+
| 0 |    0 |    1 |
+---+------+------+
| 1 |    0 | NULL |
+---+------+------+
| 2 | NULL | NULL |
+---+------+------+

There are a lot of situations where these constant values are not strictly required, for example when you have no joins, or when you could choose a non-nullable column from b instead, but they don't cause any harm either, so they can just be included unconditionally.

在很多情况下,这些常量值并不是严格要求的,例如,当您没有连接时,或者您可以从b中选择一个非空列,但是它们也不会造成任何伤害,因此可以无条件地包含它们。

#2


8  

When I have code to dynamically generate a WHERE clause, I usually start the clause with a:

当我有代码动态生成WHERE子句时,我通常以a开头:

WHERE 1 = 1

Then the loop to add additional conditions always adds each condition in the same format:

然后循环添加附加条件总是以相同的格式添加每个条件:

AND x = y

without having to put conditional logic in place to check if this is the first condition or not: "if this is the first condition then start with the WHERE keyword, else add the AND keyword.

无需使用条件逻辑检查这是否是第一个条件:“如果这是第一个条件,那么从WHERE关键字开始,否则添加AND关键字。”

So I can imagine a framework doing this for similar reasons. If you start the statement with a SELECT 0 then the code to add subsequent columns can be in a loop without any conditional statements. Just add , colx each time without any conditional checking along the lines of "if this is the first column, don't put a comma before the column name, otherwise do".

我可以想象一个框架出于类似的原因这样做。如果以SELECT 0开始语句,则添加后续列的代码可以在循环中,不包含任何条件语句。只需添加colx,每次都不需要任何条件检查,比如“如果这是第一列,不要在列名前加逗号,否则就这样做”。

Example pseudo code:

伪代码示例:

String query = "SELECT 0";

for (Column col in columnList)
    query += ", col";

#3


0  

Only Apple knows … but I see two possibilities:

只有苹果知道……但我认为有两种可能性:

  1. Inserting a dummy column ensures that the actual output columns are numbered beginning with 1, not 0. If some existing interface already assumed one-based numbering, doing it this way in the SQL backend might have been the easiest solution.

    插入一个假列可以确保实际的输出列以1开头,而不是0开头。如果一些现有的接口已经采用了基于一个的编号方式,那么在SQL后端使用这种方式可能是最简单的解决方案。

  2. If you make a query for multiple objects using multiple subqueries, a value like this could be used to determine from which subquery a record originates:

    如果您使用多个子查询对多个对象进行查询,那么可以使用这样的值来确定记录从哪个子查询开始:

    SELECT 0, t0.firstname, ... FROM PERSON t0 WHERE t0.id = 123
    UNION ALL
    SELECT 1, t0.firstname, ... FROM PERSON t0 WHERE t0.id = 456 
    

    (I don't know if Core Data actually does this.)

    (我不知道Core Data是否真的这么做。)


Your EXPLAIN output shows that the only difference is (at address 4) that the second program sets the extra column to zero, so there is only a minimal performance difference.

您的EXPLAIN输出显示惟一的区别(地址4)是第二个程序将额外的列设置为零,因此只有最小的性能差异。


推荐阅读
  • 本文详细介绍了MySQL数据库的基础语法与核心操作,涵盖从基础概念到具体应用的多个方面。首先,文章从基础知识入手,逐步深入到创建和修改数据表的操作。接着,详细讲解了如何进行数据的插入、更新与删除。在查询部分,不仅介绍了DISTINCT和LIMIT的使用方法,还探讨了排序、过滤和通配符的应用。此外,文章还涵盖了计算字段以及多种函数的使用,包括文本处理、日期和时间处理及数值处理等。通过这些内容,读者可以全面掌握MySQL数据库的核心操作技巧。 ... [详细]
  • 有没有人用过sqlite?关于tablehasnocolumnnamedcolumn插入数据的时候报上边的错。问题是我明明有这一列。直接在sqlitedevoloper里执 ... [详细]
  • IhaveonedoubtinSqlite.dteTimeDataTypeisVarchar(200)inTablestructure.Iwanttogetresult ... [详细]
  • 本文介绍如何使用 Python 的 DOM 和 SAX 方法解析 XML 文件,并通过示例展示了如何动态创建数据库表和处理大量数据的实时插入。 ... [详细]
  • MySQL Decimal 类型的最大值解析及其在数据处理中的应用艺术
    在关系型数据库中,表的设计与SQL语句的编写对性能的影响至关重要,甚至可占到90%以上。本文将重点探讨MySQL中Decimal类型的最大值及其在数据处理中的应用技巧,通过实例分析和优化建议,帮助读者深入理解并掌握这一重要知识点。 ... [详细]
  • PTArchiver工作原理详解与应用分析
    PTArchiver工作原理及其应用分析本文详细解析了PTArchiver的工作机制,探讨了其在数据归档和管理中的应用。PTArchiver通过高效的压缩算法和灵活的存储策略,实现了对大规模数据的高效管理和长期保存。文章还介绍了其在企业级数据备份、历史数据迁移等场景中的实际应用案例,为用户提供了实用的操作建议和技术支持。 ... [详细]
  • 本文介绍了如何利用Shell脚本高效地部署MHA(MySQL High Availability)高可用集群。通过详细的脚本编写和配置示例,展示了自动化部署过程中的关键步骤和注意事项。该方法不仅简化了集群的部署流程,还提高了系统的稳定性和可用性。 ... [详细]
  • com.sun.javadoc.PackageDoc.exceptions()方法的使用及代码示例 ... [详细]
  • Ihavetwomethodsofgeneratingmdistinctrandomnumbersintherange[0..n-1]我有两种方法在范围[0.n-1]中生 ... [详细]
  • javascript分页类支持页码格式
    前端时间因为项目需要,要对一个产品下所有的附属图片进行分页显示,没考虑ajax一张张请求,所以干脆一次性全部把图片out,然 ... [详细]
  • 本文详细介绍了 InfluxDB、collectd 和 Grafana 的安装与配置流程。首先,按照启动顺序依次安装并配置 InfluxDB、collectd 和 Grafana。InfluxDB 作为时序数据库,用于存储时间序列数据;collectd 负责数据的采集与传输;Grafana 则用于数据的可视化展示。文中提供了 collectd 的官方文档链接,便于用户参考和进一步了解其配置选项。通过本指南,读者可以轻松搭建一个高效的数据监控系统。 ... [详细]
  • 在处理数据库中所有用户表的彻底清除时,目前尚未发现单一命令能够实现这一目标。因此,需要采用一种较为繁琐的方法来逐个删除相关表及其结构。具体操作可以通过编写PL/SQL脚本来实现,该脚本将动态生成并执行删除表的SQL语句。尽管这种方法相对复杂,但在缺乏更简便手段的情况下,仍是一种有效的解决方案。未来或许可以通过数据库管理工具或更高版本的数据库系统提供更简洁的处理方式。 ... [详细]
  • WhenImtryingtorunthefollowing:当我试图运行以下内容时:ContentValuescvnewContentValues();cv ... [详细]
  • 我正在一个涉及SQLite的项目中,我只有一个数据库文件,现在我正在测试我的应 ... [详细]
  • SQLite–CONSTRAINTS(约束)约束是数据列在表上执行的规则。这些是用来限制的数据类型可以进入一个表。这样可以确保数据的准确性和可靠性在数据库中。    级或表级约束可 ... [详细]
author-avatar
yuliu预留
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有