在sql语句中,我们经常用到子查询,在工作中也是非常的实用,对于子查询做了以下几点总结。
1. select (select ....) as 别名 from table
第一种,在from前面的(select)子查询。这种子查询的结果只能是单行单列的,可以传递from后面表的参数进去,表示查询出来的每一行数据都是由这个查询当做一列的。
2. select * from (select * ...) table
第二种,在from后面,这种子查询会当做一个表来对待,可以有多行多列,行列没有强制要求,还可以与别的表连接查询,有一个强制要求,就是必须要写别名。不可以传递参数。
3. select * from table where table.id = (select tab.id from tab.id)
第三种,在=,>,<,>=,<=,<>,!=关系运算符后面,这种子查询的结果只能是单行单列,与关系判断符前面的数据对比。可以传递参数。
4. select * from table where table.id in(select tab.id from tab)
第四种,在in,not in的后面,数据只能是单列的,可以是一行,也可以多行,还可以是null,可以传递参数。
5. select * from table where table.id <all(select tab.id from tab )
第五种,在any,some,all这些关键字后面,只能是单列的,可以是一行,也可以是多行,还可以是null,可以传递参数。
6. select * from table where exists(select * from tab)
第六种,在exists,not exists这些关键字后面,可以是多行多列,行列没有要求,查出了数据就返回true,没查出(也就是null)就返回false,可以传递参数。所有的用in做的sql都能转成exists来做。exists效率比in要高
7. select * from table group by table.id having count(*) > (select count(tab.id) from tab)
第七种,在having 的=,>,<,>=,<=,<>,!=关系运算符后面,跟第三种是一样的约束,这种子查询的结果只能是单行单列,与关系判断符前面的数据对比。可以传递参数。
8. select * from table where table.id like (select tab.id from tab where tab.id='1')
第八种,在like的后面,返回的值只能是单行单列,因为要与table.id对比,只能是是单行单列,可以传递参数。返回的结果还能用concat(...)函数拼接。
总结:
这些经验要经常使用,才会记得牢固,多用才是硬道理。
附录一些小知识点:
some关键字等于any,some只是any的别名。
in 等价于 =any() , not in 等价于 <>all() 或者 !=all()。
遇到一个字段的含义要等效于全部的情况,用in做不了时(比如,求学了张三老师全部课程的学生信息)采用not exists来做,双层否定等于肯定。
能用in来做的都可以转换成用exists来做,而且,exists的效率比in要高。
not的位置一般都是在字段前面,表示非的意思,也就是反面,
逻辑运算符(and,or,not)
关系运算符(<>,!=,<,>,<=,>=,=),<>等价于!=