为什么选择SELECT 0,...而不是SELECT

Chr*_*nle 22 sql sqlite core-data

假设我有一个包含表的SQLite数据库:

sqlite> create table person (id integer, firstname varchar, lastname varchar);
Run Code Online (Sandbox Code Playgroud)

现在我想得到表中的每个条目.

sqlite> select t0.id, t0.firstname, t0.lastname from person t0;
Run Code Online (Sandbox Code Playgroud)

这很好用,这就是我要用的.但是,我使用了生成SQL的Apple(Core Data)框架.此框架生成略有不同的SQL查询:

sqlite> select 0, t0.id, t0.firstname, t0.lastname from person t0;
Run Code Online (Sandbox Code Playgroud)

此框架生成的每个SQL查询都以"select 0"开头.这是为什么?

我尝试使用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 
Run Code Online (Sandbox Code Playgroud)

第二个查询的表格如下所示:

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     
Run Code Online (Sandbox Code Playgroud)

小智 17

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

考虑

  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 |
+---+------+
Run Code Online (Sandbox Code Playgroud)

在此结果集中,不可能看到a = 1表B 中存在,但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 |
+---+------+------+
Run Code Online (Sandbox Code Playgroud)

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


Gle*_*enn 9

当我有动态生成WHERE子句的代码时,我通常用以下命令启动子句:

WHERE 1 = 1
Run Code Online (Sandbox Code Playgroud)

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

AND x = y
Run Code Online (Sandbox Code Playgroud)

无需放置条件逻辑来检查这是否是第一个条件:"如果这是第一个条件,则从WHERE关键字开始,否则添加AND关键字.

所以我可以想象一个框架这样做是出于类似的原因.如果用a启动语句,SELECT 0则添加后续列的代码可以在没有任何条件语句的循环中.只需添加, colx每次,而不进行任何条件检查,如果这是第一列,请不要在列名前加上逗号,否则执行".

伪代码示例:

String query = "SELECT 0";

for (Column col in columnList)
    query += ", col";
Run Code Online (Sandbox Code Playgroud)