mysql查询重复数据、函数、死锁解决

多字段删除重复数据

DELETE FROM 表名 WHERE id IN (SELECT id FROM(SELECT id FROM 表名 
WHERE (字段1,字段2) IN (SELECT 字段1,字段2 FROM (SELECT 字段1,字段2 FROM 表名 GROUP BY 字段1,字段2 HAVING COUNT(*) > 1) AS b) 
AND id NOT IN (SELECT id FROM (SELECT MIN(id) AS id FROM 表名 GROUP BY 字段1,字段2 HAVING COUNT(*)>1) AS a)) AS c);

mysql中You can’t specify target table for update in FROM clause错误的意思是说,不能先select出同一表中的某些值,再update这个表(在同一语句中)。
也就是说将select出的结果再通过中间表select一遍,这样就规避了错误。注意,这个问题只出现于mysql,mssql和oracle不会出现此问题。

多字段查询重复数据

SELECT * FROM 表名 WHERE (字段1,字段2) IN (SELECT 字段1,字段2 FROM 表名 GROUP BY 字段1,字段2 HAVING COUNT(*)>1) 
AND id NOT IN (SELECT MIN(id) FROM 表名 GROUP BY 字段1,字段2 HAVING COUNT(*)>1)

查找表中多余的重复记录,重复记录是根据单个字段(mail_id)来判断

SELECT * FROM table WHERE mail_id IN (SELECT mail_id FROM table GROUP BY mail_id HAVING COUNT(mail_id) > 1);

mysql模糊查询text字段中的json对象

查询对象下的字段

SELECT * FROM `table` bf WHERE bf.`字段` ->'$.对象名.字段名' LIKE '%ys%';
SELECT * FROM `table` bf WHERE json_extract(bf.`content`,'$.对象名.字段名') LIKE '%ys%';

查询对象下的list数组

SELECT * FROM `table` bf WHERE json_extract(json_extract(bf.`字段`,'$.对象名.xxxList'),'$[*].list中的字段名') LIKE '%ys%'

like是广泛的模糊匹配,字符串中没有分隔符,Find_IN_SET 是精确匹配,字段值以英文”,”分隔,Find_IN_SET查询的结果要小于like查询的结果

select * from article where FIND_IN_SET('4',type)

mysql数据库根据时分秒HH:mm:ss截取时分

DATE_FORMAT(summer_am_start,"%H:%i")

MySQL修改一列字符串中的指定字符

UPDATE js_sys_user_role SET user_code = REPLACE(user_code, '_', '-')

MySQL查询type字段中以 1,3,4 的格式存储

select * from table where FIND_IN_SET('4',type)

MySQL手册中find_in_set函数的语法:
FIND_IN_SET(str,strlist)
str 要查询的字符串
strlist 字段名 参数以”,”分隔 如 (1,2,6,8)
查询字段(strlist)中包含(str)的结果,返回结果为null或记录
假如字符串str在由N个子链组成的字符串列表strlist 中,则返回值的范围在 1 到 N 之间。 一个字符串列表就是一个由一些被 ‘,’ 符号分开的子链组成的字符串。
如果第一个参数是一个常数字符串,而第二个是type SET列,则FIND_IN_SET() 函数被优化,使用比特计算。 如果str不在strlist 或strlist 为空字符串,则返回值为 0 。
如任意一个参数为NULL,则返回值为 NULL。这个函数在第一个参数包含一个逗号(‘,’)时将无法正常运行。

从MySQL date_format中的%m和%d中删除前导零

SELECT `create_time`,DATE_FORMAT(create_time, '%Y/%c/%e %k:%c:%e') AS days FROM `wx_user`

mysql截取拼接

CONCAT(HOUR(a.start_time),":",MINUTE(a.start_time)) AS startTime

多列转一行

GROUP_CONCAT(`subject`,':',resuilt) '成绩'
GROUP_CONCAT(`subject`) '成绩'

分隔符拼接CONCAT_WS(separator,str1,str2,…)

– CONCAT_WS(分隔符,字符串1,字符串2,…)

SELECT
	CONCAT_WS(':','现在时间',now()) AS concats 
FROM DUAL

mysql中if判断

if(表达式,成立处理,不成立处理)

MySQL类似行转列,将字符串按指定字符分割成多列

SELECT
	substring_index(
		substring_index(
		-- 替换成a表中需分割的字段
			a.ids,
			',',
			b.help_topic_id + 1
		),
		',' ,- 1
	) id
FROM 
-- 换成自己的表
	user a
JOIN mysql.help_topic b ON b.help_topic_id < (
	length(a.ids) - length(REPLACE(a.ids, ',', '')) + 1
)
where 1=1 -- 换成自己需要的条件,或者不加条件

MySQL中保留两位小数

format

FORMAT(x,n) 格式化数据,强制保留n位小数(四舍五入),需要注意的是,返回的结果为string类型
SELECT FORMAT(1234.567,2) 的输出结果为1,234.57
SELECT FORMAT(1234,2) 的输出结果为1,234.00

round

ROUND(x,n) 数据四舍五入
SELECT ROUND(1234.567,2) 的输出结果为1234.57
SELECT ROUND(1234.567) 的输出结果为1234
SELECT ROUND(1234.567,-3) 的输出结果为1000

truncate

TRUNCATE(x,n)返回小数点后n位的数据
SELECT TRUNCATE(1234.567,2) 的输出结果为1234.56

convert

CONVERTvaluetype) 类型转换,CONVERT()函数会对小数部分进行四舍五入操作
SELECT CONVERT(1234.567,DECIMAL(10,2)) 的输出结果为 1234.57

Mysql 查询是否存在锁表有多种方式,这里只介绍一种最常用的。

1、查看正在进行中的事务

SELECT * FROM information_schema.INNODB_TRX

2、查看正在锁的事务

SELECT * FROM INFORMATION_SCHEMA.INNODB_LOCKS;

3、查看等待锁的事务

SELECT * FROM INFORMATION_SCHEMA.INNODB_LOCK_WAITS;

4、查询是否锁表

在发生死锁时,这几种方式都可以查询到和当前死锁相关的信息。

SHOW OPEN TABLES where In_use > 0;

5、查看最近死锁的日志

show engine innodb status

解除死锁(在服务器中进行)

如果需要解除死锁,有一种最简单粗暴的方式,那就是找到进程id之后,直接干掉。
查看当前正在进行中的进程

首先需要在linux中登录mysql这里就不讲了

show processlist

也可以使用

SELECT * FROM information_schema.INNODB_TRX;

这两个命令找出来的进程id 是同一个。
杀掉进程对应的进程 id

kill id

验证(kill后再看是否还有锁)

SHOW OPEN TABLES where In_use > 0;

参考链接:Mysql死锁问题如何排查和解决

你可能感兴趣的:(java开发安装及配置,mysql,数据库)