MySQL使用学习记录


  • 2017.8.18 find_in_set函数
    find_in_set函数

FIND_IN_SET(str,strlist)

假如字符串str 在由N 子链组成的字符串列表strlist 中,则返回值的范围在 1 到 N 之间。
一个字符串列表就是一个由一些被‘,’符号分开的子链组成的字符串。如果第一个参数是一个常数字符串,而第二个是type SET列,则 FIND_IN_SET() 函数被优化,使用比特计算。
如果str不在strlist 或strlist 为空字符串,则返回值为 0 。如任意一个参数为NULL,则返回值为 NULL。这个函数在第一个参数包含一个逗号(‘,’)时将无法正常运行。

基本用法:

select FIND_IN_SET('2','1,2');返回2 
select FIND_IN_SET('6','1'); 返回0 

关联查询:用(x,y,z)存储同表或另一张表中的字段值,如多个id(以逗号隔开),关联查询多条记录。

SELECT
	*
FROM
	zz,
	classify c
WHERE
	FIND_IN_SET(
		c.id,
		(
			SELECT
				zzid
			FROM
				zz
			WHERE
				zz.id = 1
		)
	)

结果:
mysql中find_in_set函数


  • 2017.8.21 truncate table清空表并重置自增id
    使用truncate 表名清空某张表并重置该表的自增id,但无法操作有外键约束的表

  • 2017.9.2记录 MySQL删除一个数据库中的所有表
  1. 用图形工具多选删除。
  2. 先用select语句获取所有表的删除语句,然后全选复制执行。有外键的需要先暂时关闭外键约束检查。
SELECT CONCAT('drop table ',table_name,';') FROM information_schema.`TABLES` WHERE table_schema='数据库名';
set foreign_key_checks=0;     //关闭外键检查

set foreign_key_checks=1;  //打开外键检查

//执行第一条select的复制结果
drop table account;
drop table address;
drop table admin;
drop table admin_authority;
……
…

  • 2017.11.1 Date相关,按天、周、月、年统计
知识关键词:DATE_FORMAT 
select DATE_FORMAT(create_time,'%Y%u') weeks,count(caseid) count from tc_case group by weeks;  
select DATE_FORMAT(create_time,'%Y%m%d') days,count(caseid) count from tc_case group by days;  
select DATE_FORMAT(create_time,'%Y%m') months,count(caseid) count from tc_case group by months; 
DATE_FORMAT(date,format) 
根据format字符串格式化date值。下列修饰符可以被用在format字符串中: 
%M 月名字(January……December) 
%W 星期名字(Sunday……Saturday) 
%D 有英语前缀的月份的日期(1st, 2nd, 3rd, 等等。) 
%Y 年, 数字, 4 位   www.2cto.com  
%y 年, 数字, 2 位 
%a 缩写的星期名字(Sun……Sat) 
%d 月份中的天数, 数字(00……31) 
%e 月份中的天数, 数字(0……31) 
%m 月, 数字(01……12) 
%c 月, 数字(1……12) 
%b 缩写的月份名字(Jan……Dec) 
%j 一年中的天数(001……366) 
%H 小时(00……23) 
%k 小时(0……23) 
%h 小时(01……12) 
%I 小时(01……12) 
%l 小时(1……12) 
%i 分钟, 数字(00……59) 
%r 时间,12 小时(hh:mm:ss [AP]M) 
%T 时间,24 小时(hh:mm:ss) 
%S 秒(00……59) 
%s 秒(00……59) 
%p AM或PM 
%w 一个星期中的天数(0=Sunday ……6=Saturday ) 
%U 星期(0……52), 这里星期天是星期的第一天 
%u 星期(0……52), 这里星期一是星期的第一天 
%% 一个文字“%”。

示例

当天
SELECT
	*
FROM
	orders
WHERE
	TO_DAYS(now()) = TO_DAYS(pay_datetime)

SELECT
	*
FROM
	orders
WHERE
	date(now()) = date(pay_datetime)


一周
SELECT
	*
FROM
	`orders`
WHERE
	date(
		date('2017-10-13 18:31:24') - WEEKDAY(
			date('2017-10-13 18:31:24')
		)
	) <= pay_datetime
AND pay_datetime <= DATE_ADD(
	date(
		date('2017-10-13 18:31:24') - WEEKDAY(
			date('2017-10-13 18:31:24')
		)
	),
	INTERVAL 6 DAY);

一周 (yearweek(date,first)),first参数取1即可
SELECT
	*
FROM
	orders
WHERE
	yearweek('2017-11-01', 1) = yearweek(pay_datetime, 1);


SELECT
	*
FROM
	`orders`
WHERE
	date(pay_datetime) > last_day('2017-10-02');

当月第一天
SELECT
	date(
		concat(DATE_FORMAT('2017-10-02', '%Y-%m'),'-','1')
	);


一月
SELECT
	*
FROM
	orders
WHERE
	DATE_FORMAT(pay_datetime, '%Y%m') = DATE_FORMAT(CURDATE(), '%Y%m');

一月
SELECT
	*
FROM
	`orders`
WHERE
	date(
		concat(
			YEAR ('2017-10-13 18:31:24'),
			'-',
			MONTH (curdate()),
			'-',
			'1'
		)
	) < pay_datetime
AND pay_datetime < LAST_DAY('2017-10-13 18:31:24');


当年
SELECT
	*
FROM
	orders
WHERE
	YEAR (now()) = YEAR (pay_datetime)

  • 2017.11.21 statistics report
//每月销售报总表 

	SELECT
	g.goods_name goodsName,
	g.m_price price,
	sum(sku_count) saleCount,
	count(DISTINCT(og.order_id)) orderCount,
	sum(sex = '男') AS male,
	sum(sex = '女') AS female,
	sum(
		(YEAR(now()) - YEAR(birthday)) < 20
	) ltTwenty,
	sum(
		(YEAR(now()) - YEAR(birthday)) >= 20
		AND (YEAR(now()) - YEAR(birthday)) <= 30
	) twenty2thirty,
	sum(
		(YEAR(now()) - YEAR(birthday)) > 30
		AND (YEAR(now()) - YEAR(birthday)) <= 40
	) thirty2forty,
	sum(
		(YEAR(now()) - YEAR(birthday)) > 40
		AND (YEAR(now()) - YEAR(birthday)) <= 50
	) forty2fifty,
	sum(
		(YEAR(now()) - YEAR(birthday)) > 50
	) gtFifty
FROM
	order_goods og
INNER JOIN goods g ON (og.goods_id = g.id)
INNER JOIN orders o ON (og.order_id = o.id)
INNER JOIN muser m ON (o.muser_id = m.id)
WHERE
	DATE_FORMAT(pay_datetime, '%Y%m') = DATE_FORMAT(CURDATE(), '%Y%m')
GROUP BY
	goodsName
ORDER BY
	saleCount DESC;

地区销售占比表 SELECT
	a.city,
	sum(total_price) turnover,
	count(*) orderCount,
	ROUND(
		(
			sum(total_price) / (
				SELECT
					sum(total_price)
				FROM
					orders
				WHERE
					DATE_FORMAT(orders.pay_datetime, '%Y%m') = DATE_FORMAT(CURDATE(), '%Y%m')
			)
		),
		4
	) cityTurnoverRate,
	count(*) orderCount,
	ROUND(
		(
			count(*) / (
				SELECT
					count(*)
				FROM
					orders
				WHERE
					DATE_FORMAT(orders.pay_datetime, '%Y%m') = DATE_FORMAT(CURDATE(), '%Y%m')
			)
		),
		4
	) cityCountRate,
	sum(sex = '男') AS male,
	sum(sex = '女') AS female,
	sum(
		(YEAR(now()) - YEAR(birthday)) < 20
	) ltTwenty,
	sum(
		(YEAR(now()) - YEAR(birthday)) >= 20
		AND (YEAR(now()) - YEAR(birthday)) <= 30
	) twenty2thirty,
	sum(
		(YEAR(now()) - YEAR(birthday)) > 30
		AND (YEAR(now()) - YEAR(birthday)) <= 40
	) thirty2forty,
	sum(
		(YEAR(now()) - YEAR(birthday)) > 40
		AND (YEAR(now()) - YEAR(birthday)) <= 50
	) forty2fifty,
	sum(
		(YEAR(now()) - YEAR(birthday)) > 50
	) gtFifty
FROM
	orders o
INNER JOIN muser m ON (o.muser_id = m.id)
INNER JOIN address a ON (m.id = a.muser_id)
WHERE
	a.tag = '0'
AND DATE_FORMAT(o.pay_datetime, '%Y%m') = DATE_FORMAT(CURDATE(), '%Y%m')
GROUP BY
	a.city
ORDER BY
	orderCount DESC 每月区域销售表 SELECT
		g.goods_name goodsName,
		g.m_price price,
		sum(sku_count) saleCount,
		a.city,
		sum(sex = '男') AS male,
		sum(sex = '女') AS female,
		sum(
			(YEAR(now()) - YEAR(birthday)) < 20
		) ltTwenty,
		sum(
			(YEAR(now()) - YEAR(birthday)) >= 20
			AND (YEAR(now()) - YEAR(birthday)) <= 30
		) twenty2thirty,
		sum(
			(YEAR(now()) - YEAR(birthday)) > 30
			AND (YEAR(now()) - YEAR(birthday)) <= 40
		) thirty2forty,
		sum(
			(YEAR(now()) - YEAR(birthday)) > 40
			AND (YEAR(now()) - YEAR(birthday)) <= 50
		) forty2fifty,
		sum(
			(YEAR(now()) - YEAR(birthday)) > 50
		) gtFifty
	FROM
		order_goods og
	INNER JOIN goods g ON (og.goods_id = g.id)
	INNER JOIN orders o ON (og.order_id = o.id)
	INNER JOIN muser m ON (o.muser_id = m.id)
	INNER JOIN address a ON (m.id = a.muser_id)
	WHERE
		DATE_FORMAT(pay_datetime, '%Y%m') = DATE_FORMAT(CURDATE(), '%Y%m')
	AND a.tag = '0'
	GROUP BY
		goodsName,
		a.city
	ORDER BY
		goodsName,
		saleCount DESC;

//订单年月查询
SELECT
	sum(summ),
	paymonthflag
FROM
	(
		SELECT
			sum(total_price) summ,
			count(*) cnt,
			count(pay_datetime),
			MONTH (pay_datetime) paymonthflag,
			MONTH (gmt_datetime) monthflag
		FROM
			orders
		WHERE
			YEAR (gmt_datetime) = 2017
		GROUP BY
			monthflag,
			paymonthflag
	) AS zz
WHERE
	paymonthflag IS NOT NULL
GROUP BY
	paymonthflag;

SELECT
	sum(total_price) monthPay,
	sum(delivery_money) monthDelivery,
	sum(coupon_val) monthCoupon,
	count(*) monthPayCount,
	MONTH (pay_datetime) monthPayFlag
FROM
	orders
WHERE
	YEAR (pay_datetime) = 2017
GROUP BY
	monthPayFlag;

SELECT
	sum(total_price)
FROM
	orders
WHERE
	YEAR (pay_datetime) = 2017;

//购买次数 
SELECT
	count(1) purchaseCount
FROM
	(
		SELECT
			COUNT(1) countP
		FROM
			muser m
		LEFT JOIN orders o ON (m.id = o.muser_id)
		WHERE
			o.pay_type IS NOT NULL
		AND m.user_name IS NOT NULL
		GROUP BY
			m.id
		HAVING
			count(m.id) >= 2
	) t



  • MySQL sum()函数参数为表达式

原数据:

select * from student;
原数据

sum条件表达式命令:

SELECT class_id, SUM(sex = '男') AS male, SUM(sex = '女') AS female FROM student
GROUP BY class_id

结果:
结果


  • 2018.2.28 参考数据库设计范式

    不一定要完全遵循范式,只是作为参考,例如多图上传只用一个字段逗号将url隔开不符合第一范式,但不影响核心业务且能简化实现。

第一范式(1NF)属性不可分。是指在关系模型中,对域添加的一个规范要求,所有的域都应该是原子性的,即数据库表的每一列都是不可分割的原子数据项。

第二范式(2NF)在1NF的基础上,非码属性必须完全依赖于候选码(在1NF基础上消除非主属性对主码的部分函数依赖)

第三范式(3NF)在1NF基础上,任何非主属性不依赖于其它非主属性(在2NF基础上消除传递依赖)

巴斯-科德范式(BCNF)Boyce-Codd Normal Form(巴斯-科德范式)在1NF基础上,任何非主属性不能对主键子集依赖(在3NF基础上消除对主码子集的依赖)

***********************前四个常用************************

第四范式(4NF),要求把同一表内的多对多关系删除。

第五范式(5NF),又称完美范式,从最终结构重新建立原始结构。


  • 2018.3.21 group_concat()函数
    MySQL ***GROUP_CONCAT()***函数将组中的非NULL字符串连接成为具有各种选项的单个字符串
    group_concat
    DISTINCT去重,ORDER BY排序,SEPARATOR指定分隔符(默认逗号)。更重要的是还可以和group by配合使用连接各个组中的指定字段
SELECT 
    employeeNumber,
    firstName,
    lastName,
    GROUP_CONCAT(DISTINCT customername
        ORDER BY customerName)
FROM
    employees
        INNER JOIN
    customers ON customers.salesRepEmployeeNumber = employeeNumber
GROUP BY employeeNumber
ORDER BY firstName , lastname;

  • case when

case when (条件) then XX when (条件) else XX end,为指定值赋值排序,相当于oracle中的decode,可以在select (case when …)as 结果字段,当作结果,也可以用于特定值优先的排序。
如3月份的在最前,其他月份排后,可以用order by case when month=3 then 1 else 2 end asc 来排序。

SELECT 
(case term_month when term_month=3  then 1 when (term_month<>0 and term_month<>3) then 2 else 3 end) zzz

FROM ZXZ

ORDER BY money_level desc,
case term_month when term_month=3  then 1 
when (term_month<>0 and term_month<>3) then 2 else 3 end,
case length when 45 then 3 when 30 then 4 else 5 end 

  • 2018.7.25 MySQL比较两个时间字段大小,取较大者,case when
    两个时间字段中有可能有的为NULL,先取时间not null的,都有时间则取较大者。
    思路:用case when配合if语句将取值统一用时间戳比较大小,NULL作为时间戳的0。
select 
(CASE WHEN IF (time_field_A IS NULL,0,UNIX_TIMESTAMP(time_field_A)) > IF (time_field_B IS NULL,0,UNIX_TIMESTAMP(time_field_B)) THEN time_field_A ELSE time_field_B END) greater_time
from table

  • 对于select 语句,innodb不会加任何锁,也就是可以多个并发去进行select的操作,不会有任何的锁冲突,因为根本没有锁。
  • 对于insert,update,delete操作,innodb会自动给涉及到的数据加排他锁,只有查询select需要我们手动设置排他锁

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值