SQL的一些注意事项

SQL总结

1)find_in_set

查询表中的某列是否存在单个值(或者集合中的值)

部门id查询,(父部门可以查所有子部门)

ancestors为祖级列表
FROM tb_school WHERE company_id IN(SELECT dept_id FROM sys_dept WHERE (find_in_set(#{companyId}, ancestors)) or dept_id= #{companyId})

2)replace into

replace是insert的增强版
replace into 首先尝试插入数据到表中,
1. 如果发现表中已经有此行数据(根据主键或者唯一索引判断)则先删除此行数据,然后插入新的数据。 

2. 否则,直接插入新数据

3)ON DUPLICATE KEY UPDATE

配合mybatis的insert

<insert id="saveOrUpdateYiYuan" parameterType="java.util.List">
        insert into yiyuan
        (id,agent,enterprise,operator,remark)
        values
        <foreach collection="listData" item="item" index="index" separator=",">
            (#{item.id},#{item.agent},#{item.enterprise},#{item.operator},#{item.remark})
        </foreach>
        ON DUPLICATE KEY UPDATE
        id = values(id),
        agent = values(agent),
        enterprise = values(enterprise),
        operator = values(operator),
        remark = values(remark)
</insert>

根据集合加入信息,如果 数据重复-ON DUPLICATE KEY UPDATE(唯一索引)则执行更新      

4)SQL的事件调度器

(例子1): 定时删除15天前的数据

1.首先需要查看是否开启了“事件调度器”

 show variables like '%sc%';  

2.开启事件(mysql服务重启后之后失效)

SET GLOBAL event_scheduler = ON; SET GLOBAL event_scheduler = 1; — 1为开启

3.创建事件

DELIMITER $$
DROP EVENT IF EXISTS 事件名;
CREATE EVENT 事件名
ON SCHEDULE EVERY 15 DAY STARTS '2022-09-27 17:59:55'
ON COMPLETION PRESERVE
DO BEGIN
delete fromwhere TO_DAYS(now())-TO_DAYS(字段)>15;
END$$
DELIMITER ;

4.开启事件

alter event 事件名 on completion preserve enable;

5.关闭事件

alter event 事件名 on completion preserve disable;

6.删除事件

drop event if exists 事件名;

5)动态表名

<update id="unifiedUpdate">
        update ${tableName}
        set approval_status = #{status}
        where id = #{id}
</update>

要注意:#使用预编译,$使用拼接SQL。

当字段为String时,SQL是否需要带引号,$时不带' ',#带' '。防注入也是因为这个原因

Mybatis的SQL注入 : https://blog.csdn.net/M983373615/article/details/118696823

6)concat类型

一、concat()函数

1、功能:将多个字符串连接成一个字符串。

2、语法:concat(str1, str2,...)

说明:返回结果为连接参数产生的字符串,如果有任何一个参数为null,则返回值为null。

3、举例:select concat (id, name, score) as 别名 from 表名;

二、concat_ws()函数

1、功能:和concat()一样,但是可以指定分隔符(concat_ws就是concat with separator)

2、语法:concat_ws(separator, str1, str2, ...)

说明:第一个参数指定分隔符。需要注意的是分隔符不能为null,如果为null,则返回结果为null。

3、举例:select concat ('#',id, name, score) as 别名 from 表名;

三、group_concat()函数

1、功能:将group by产生的同一个分组中的值连接起来,返回一个字符串结果。

2、语法:group_concat( [distinct] 要连接的字段 [order by 排序字段 asc/desc ] [separator] )

说明:通过使用distinct可以排除重复值;如果希望对结果中的值进行排序,可以使用order by子句;separator分隔符是一个字符串值,缺省为一个逗号。

3、举例:select name,group_concat(id order by id desc separator '#') as 别名 from 表名 group by name;

四、concat_ws()和group_concat()联合使用

题目:查询以name分组的所有组的id和score

举例:select name,group_concat(concat_ws('-',id,score) order by id) as 别名 from 表名 group by name;

 

在update中使用 case

@Transactional
@Modifying
@Query(value = " update group_pk_room A \n" +
        "set people_num = (CASE WHEN ?2 = 1 THEN people_num - 1 ELSE A.people_num END),   \n" +
        "room_num = (CASE WHEN ?2 = 2 THEN room_num - 1 ELSE A.room_num END)  \n" +
        "WHERE id = ?1 ",nativeQuery=true)

EXISTS的一些用法

MySQL中EXISTS的用法 - QiaoZhi - 博客园 (cnblogs.com)

if (position!=null && !StringUtils.isEmpty(position)){
sql.append(" AND exists ( select 1 from course_to_buwei ctb where ctb.buwei_label_id=:position and ctb.course_id=c.id ) ");
params.put("position",position);
}

 

GROUP BY优化,

GROUP BY 会默认进行一次隐性排序,可以通过 order by NULL,优化查询速度

SELECT course_field_id from course_field_to_course_topic GROUP BY course_field_id order by NULL;

尽量少用DISTINCT ,多用GROUP BY,底层查询速度差不多,但是GROUP BY 可以做COUNT()等一系列函数操作。

select DISTINCT course_field_id from course_field_to_course_topic;

 

MySQL报错:sql_mode=only_full_group_by 4种解决方法含举例,轻松解决ONLY_FULL_GROUP_BY的报错问题

5.7之后的版本,会出现这种错误。因为SELECT 的字段,没有出现在GROUP BY中。可以通过聚合函数MAX(查询字段),MIN(查询字段),去显示出来。

或者直接修改数据库配置

select @@global.sql_mode;

如果没有出现(ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ENGINE_SUBSTITUTION

就去设置就去

SET GLOBAL sql_mode='STRICT_TRANS_TABLES,NO_ENGINE_SUBSTITUTION';

 

posted @ 2022-09-19 16:21  Sjh_code  阅读(170)  评论(0编辑  收藏  举报