- 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
)
)
结果:
- 2017.8.21 truncate table清空表并重置自增id
使用truncate 表名清空某张表并重置该表的自增id,但无法操作有外键约束的表
- 2017.9.2记录 MySQL删除一个数据库中的所有表
- 用图形工具多选删除。
- 先用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字符串连接成为具有各种选项的单个字符串
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需要我们手动设置排他锁。