from(on>join)>where>group by>聚合函数(sum,min,max,avg,count)>having>order
by>select >limit
顺序:表结合 筛选 分组 聚合 组筛选 排序 求结果
where 后不能用聚合函数,因为where先于聚合函数执行
having,order by,select 后都可用聚合函数
1.包括null值
COUNT(*)
COUNT(1)
2.不包括null值 count(列名)
在InnoDB中COUNT(*)和COUNT(1)实现上没有区别
MyISAM做了一个简单的优化,把表的总行数单独记录下来,如果执行count(*)
时可以直接返回
例子理解:用户表 订单表 显示所有用户的订单信息,包括买过东西的。
1.对单表的筛选加在on上,不要加在where上。尤其是需要保留值为null的记录的情况下只能加在on上。
因为on是先筛选后连接,where是先连接后筛选。
图示
group by
与distinct
两者无需对同一字段共用,因为都能起到去重作用
SELECT DISTINCT A FROM TABLE;
SELECT A FROM Table GROUP BY A;
null值是不能进行大小比较的。必须用ifnull函数先转化为0值
可以直接用在字段位置
赋值位置
或者聚合函数内
1.CASE
SELECT name,score,(CASE
WHEN score>=90 THEN '优秀'
WHEN score>=80 THEN '良好'
WHEN score>=60 THEN '及格'
ELSE '不及格' END) level
FROM score
2.if
select *,if(sva=1,"男","女") as ssva from taname where sva != ""
3.IFNULL
select id,IFNULL(phone,mobile) phone from t_service_org limit 10
如果phone不为null,输出phone值,否则输出mobile值
4.WHEN THEN ELSE END
SET
sex = CASE sex
WHEN 'm' THEN 'f'
ELSE 'm'
END;
1.year()取年
2.datediff(‘2019-07-27’, activity_date) 计算日期差,后减前
datediff('2019-07-27', activity_date) <30 30天内,包括7.27
3.group_concat(A)
和分组连用。把同组A字段的值聚合到一个单元格内
例如:按部门显示 姓名
例子
4.排名函数
ROW_NUMBER() 每一条数据加一个序号,同分不同号
RANK() 同分同号 1 1 2
DENSE_RANK() 同分同号 1 1 3
NTILE()函数是将有序分区中的行分发到指定数目的组
SELECT ROW_NUMBER() OVER(PARTITION BY class_no ORDER BY score DESC) AS Row, FirstName, LastName"
FROM students
同表同记录不同字段,直接比较即可
同表同字段,需要自连接
select w2.id from Weather w1 cross join Weather w2 on DATEDIFF(w2.RecordDate, w1.RecordDate) = 1 AND w2.Temperature > w1.Temperature
0.明确输入表字段,输出字段
1.问题分解,转化为单元操作
2.表连接时,根据共同字段和所需明确连接关系
例如
第二高的薪水:排序+取2号