相信第一次看到下面这个SQL的同学心里都不免会产生疑问。
SELECT * FROM employees
WHERE 1=1
为什么要在where条件中使用1=1这样的写法?这不是废话吗?
其实还真不是。
为什么使用1=1这样的条件?
在SQL语句中,当需要拼接多个条件时,我们可能会使用AND或OR来连接这些条件。而有时,为了拼接条件更加方便,会在where条件后直接写上1=1,这其实是为了简化拼接条件的逻辑表达式。
SELECT * FROM employees
WHERE 1=1
AND age > 25
AND gender = 'male';
比如,上面这个例子中,当我们写上1=1之后,在下面拼接其他条件时,不再需要额外判断是否是第一个条件,也不需要额外添加AND或者OR的逻辑判断。它就相当于一个空白的条件,可以让我们轻松地在后面添加新的条件,而不用纠结于第一个条件是否需要添加AND。
这种写法在动态拼接SQL语句时非常方便,也让代码看起来更加清晰明了。既提高了代码的可读性,又让我们的SQL语句更加优雅。
并且在我们想要注释掉某一个条件时,直接在该条件前使用单行注释符“--”就可以了,非常的方便。
“1=1”的其他高级场景:多表关联
看起来,“1=1”的逻辑判断条件永远为TRUE,似乎在SQL语句中并没有起到什么效果。
但在下面这个场景中,少了它,好像还真不行。
select
a.city_id,
b.product_id,
coalesce(c.in_come,0)
from t_city a
inner join t_product b
on 1=1
left join t_in_come c
on a.city_id = c.city_id
and b.product_id = c.product_id;
这个SQL有些复杂,使用了两张维表(t_city、t_product)和一张统计结果表(t_in_come)。
假如t_in_come表中保存了每个城市、每个产品的收入汇总数据,但对于那些某些产品并没有产生收入的城市,在表中并没有记录。
此时,如果想返回每个城市、每个产品的收入汇总,包括那些未产生收入的产品、城市组合。
怎么办呢?
在上面的例子中,先将两张维表关联起来,生成城市和产品的所有排列组合,再左关联出对应的收入数据。
在这里,内关联+“1=1”的条件组合,作用其实相当于笛卡尔积。
这种用法,在数据可视化的报表展示场景非常常见。
“1<>1”用于拷贝表定义
除了“1=1”,“1<>1”也有它的用武之地。
假如有一张表a,此时想创建一张与a的表结构完全相同的表b。
一般来说,首先会拷贝a表的create table语句,将a替换成b,然后进行表的创建。
但这样操作,可能会存在2个问题。
一方面,这样操作很麻烦,需要先获取a表的create table语句;
另一方面,如果在运行程序的过程中,a表的表结构并不是完全固定的,无法事先获知a表的create table语句,那也就无法创建出同样结构的b表。
事实上,这时候可以活用SQL中的“create table ** as **”语法。
比如下面的SQL:
create table b
as
select * from a
where 1<>1;
这时,b表完全拷贝a表的定义,而因为使用了“1<>1”的条件,导致select子句查不到任何数据,从而实现了只拷贝结构而不拷贝数据的效果。
“2=2”与“'a'='a'”又是什么鬼?
既然有“1=1”这样的写法,那写“2=2”、“'a'='a'”行不行呢?
事实上,完全可行!
它们的本质都是使用一个相同的常量形成一个相等的判断条件,返回一个永远为true的结果。
类似的,如果要返回一个永远为false的结果,除了使用“1<>1”外,还可以使用“2<>2”与“'a'<>'a'”。
甚至于,还可以使用“1=0”与“'a'<>'b'”。