![4424782f35a62da3a6112502ec01603d.png](https://img-blog.csdnimg.cn/img_convert/4424782f35a62da3a6112502ec01603d.png)
1.exists与in
select * from 表A where id in (select id from 表B)
上面sql语句相当于
select * from 表A where exists(select 1 from 表B where 表 B.id = 表A.id)
区分in和exists主要是造成了驱动顺序的改变(这是性能变化的关键),如果是exists,那么以外层表为驱动表,先被访问,如果是IN,那么先执行子查询。所以IN适合于外表大而内表小的情况;EXISTS适合于外表小而内表大的情况。
一种通俗的可以理解为:将外查询表的每一行,代入内查询作为检验,如果内查询返回的结果取非空值,则EXISTS子句返回TRUE,这一行行可作为外查询的结果行,否则不能作为结果。
2.前端传递筛选值为逗号拼接
比如前端是部门复选框,数据传递到后端是逗号拼接的部门ids,
一种方法是通过split进行逗号拆分成子查询:
SELECT items department FROM dbo.splitl(:departments,',')
第二种是通过charindex函数:
charindex(','+cast(u.department as varchar)+',' , ','+:departments+',')>0
将数据库中的department左右两边填充逗号,再与前端返回的departments比较,看是否存在这个索引
3.left join中on条件和where条件的区别
有 A left join B on .. where .. and 这条sql:
1、on and 不会过滤结果记录条数,只会根据and后的条件是否显示 B表的记录,A表的记录一定会显示。
2、不管on and 是A.id=1还是B.id=1,都显示出A表中所有的记录,并关联显示B中对应A表中id为1的记录或者B表中id为1的记录。
数据库在通过连接两张或多张表来返回记录时,都会生成一张中间的临时表,然后再将这张临时表返回给用户。
在使用left jion时,on和where条件的区别如下:
1、on条件是在生成临时表时使用的条件,它不管on中的条件是否为真,都会返回左边表中的记录。
2、where条件是在临时表生成好后,再对临时表进行过滤的条件。这时已经没有left join的含义(必须返回左边表的记录)了,条件不为真的就全部过滤掉。
4.如何理解出现在SELECT子句中的单独的列,必须出现在GROUP BY子句中作为分组列
有两条sql如下:
SELECT s_id from score GROUP BY s_id;
SELECT c_id from score GROUP BY s_id;
第二条就会报错,
原因:
这个是按照s_id分组的,
分组是什么意思,把数据按照某种特征进行划分,相同组的特征相同,不同组的特征不同,那么分完组后,我同组内的数据的s_id是不是都相同?
说通俗点:GROUP BY s_id意思是将所有具有相同s_id字段值的记录放到一个分组里。那么GROUP BY s_id, c_id 呢?GROUP BY s_id, c_id 意思是将所有具有相同s_id字段值和c_id 字段值的记录放到一个分组里。
我们去在select s_id,数据库会选择按照s_id分组后的一条记录显示,因为我们就是按照sid分组的,相同的组中s_id相同,但是为啥不出现在GROUP BY子句中的字段不能选择呢,比如cid字段,因为同一组中c_id可能不相同,但是显示的时候只能取一条,所以取到的值可能正确也可能不正确,
同时也必须结合组合函数,不然分组没意义
5.交换两行数据的排序值
update pt set pt.order_no = (case when id = 1896 then (select order_no from pm_task where id = 1895) when id = 1895 then (select order_no from pm_task where id = 1896) end) from pm_task pt where pt.id in (1895,1896)
6.同一张表中的count计数
select pt.id,pt.name,(select count(1) from pm_task where parent_task_id = pt.id) son_task_num from pm_task pt
。。。。。未完待续