我知道在oracle / mysql / sqlserverselect语句中,您不能在where子句中引用列别名,因为它是在之前执行的select,但它在sqlite3中有效:
select
where
sqlite> create table t (c1 text, c2 text); sqlite> insert into t values ("a1", "a2"); sqlite> insert into t values ("b1", "b2"); sqlite> select c1, c2 from t; a1|a2 b1|b2 sqlite> select c1, c2 as alias_c2 from t where alias_c2='b2'; b1|b2
为什么在sqlite中这有可能?
使用SQLITE_DEBUG启用了标志的sqlite3 :
SQLITE_DEBUG
sqlite> create table x (x1 integer); sqlite> insert into x values (1); sqlite> insert into x values (2); sqlite> insert into x values (3); sqlite> insert into x values (4); sqlite> insert into x values (5); sqlite> pragma vdbe_listing=1; VDBE Program Listing: 0 Expire 0 0 0 00 1 Halt 0 0 0 00 sqlite> select x1*x1 as s from x where s>-10 and s>-9 and s>0 and s>-4 and s>2; VDBE Program Listing: 0 Trace 0 0 0 00 1 Integer -10 1 0 00 2 Integer -9 2 0 00 3 Integer 0 3 0 00 4 Integer -4 4 0 00 5 Integer 2 5 0 00 6 Goto 0 26 0 00 7 OpenRead 0 3 0 1 00 x 8 Rewind 0 24 0 00 9 Column 0 0 7 00 x.x1 10 Multiply 7 7 6 00 11 Le 1 23 6 6A 12 Multiply 7 7 6 00 13 Le 2 23 6 6A 14 Multiply 7 7 6 00 15 Le 3 23 6 6A 16 Multiply 7 7 6 00 17 Le 4 23 6 6A 18 Multiply 7 7 6 00 19 Le 5 23 6 6A 20 Column 0 0 6 00 x.x1 21 Multiply 6 6 9 00 22 ResultRow 9 1 0 00 23 Next 0 9 0 01 24 Close 0 0 0 00 25 Halt 0 0 0 00 26 Transaction 0 0 0 00 27 VerifyCookie 0 4 0 00 28 TableLock 0 3 0 x 00 29 Goto 0 7 0 00 s ---- 4 9 16 25 sqlite>
从上面的指令堆栈可以看出,行的循环(第8-23行)针对表中的每一行对子句中的每个表达式重复执行MultiplyandLe命令where。
Multiply
Le
因此,要回答我自己的问题,sqlite引擎能够通过select在执行时替换列的别名来使用列别名where。