基础查询
select * from users;
去重查询 distinct
- 去重标志符 distinct 需要放到前面, 放到后面会报错
- 去重的是选择列的组合去重
select distinct user, password from users; # user, password 组合去重
排序 - 结果排序 (order by)
语法: order by user desc, password asc
- desc: 降序排列
- asc(默认): 升序排列.
# 例: 查询 users 表中用户名, 密码, 排序展示, 由 user 降序排列, 如果 user 相同, password 升序排列.
select user, password from users
order by user desc, password asc;
子查询
语法: select * from users where userId in (select userId from address where city = '北京');
查询结果被作为供其他的查询语句使用.
连接查询
连接查询分类
- 交叉连接 (笛卡尔乘积) select * from boys, beauty; (笛卡尔乘积现象:表1 有m行,表2有n行,结果=m*n行)
- 内连接(inner join) 保留交叉部分. select * from a inner join b where a.id = b.id;
- 左外连接(left join .. on): 保留A全部, 以及与B 相交的位置. select * from a left join b on a.id = b.id;
- 右外连接(right join ... on): 保留B全部, 以及与A 相交的位置 select * from a right join b on a.id = b.id;
分组查询
MySQL 的分组查询是一个聚合操作. 语法为: group by xxx having xxx
SELECT SUM(salary),job_id FROM employees
GROUP BY job_id
HAVING job_id > 0 # 条件.
1. 分组查询注意项
注意项:
默认情况下分组中select后面的列只能有2种:
- 出现在group by后面的列
- 使用聚合函数的列.
查询语句的执行顺序:
select、from、where、group by、having、order by、limit
2. where和having的区别
- where是在分组(聚合)前对记录进行筛选,而having是在分组结束后的结果里筛选,最后返回整个sql的查询结果。
- 可以把having理解为两级查询,即含having的查询操作先获得不含having子句时的sql查询结果表,2.2. 然后在这个结果表上使用having条件筛选出符合的记录,最后返回这些记录,因此,having后是可以跟聚合函数的,并且这个聚集函数不必与select后面的聚集函数相同。
3. 分组查询示例
#1. 正常能出结果的.
mysql> SELECT MIN(salary),manager_id FROM employees WHERE manager_id IS NOT NULL
GROUP BY manager_id
HAVING MIN(salary)>=6000;
+-------------+------------+
| MIN(salary) | manager_id |
+-------------+------------+
| 9000.00 | 102 |
| 6900.00 | 108 |
| 8300.00 | 205 |
+-------------+------------+
# 其中 manager_id 为分组列, salary 为聚合函数 MIN 使用的列, 所以能出结果
分页查询
1. 分页查询注意点
语法: select * from 表 limit [offset, ] size;
2. 分页查询示例
mysql> SELECT employee_id,first_name FROM employees limit 15,5;
+-------------+------------+
| employee_id | first_name |
+-------------+------------+
| 115 | Alexander |
| 116 | Shelli |
| 117 | Sigal |
| 118 | Guy |
| 119 | Karen |
+-------------+------------+
联合查询(union, union all)
1. 联合查询特征
union 联合 合并:将多条查询语句的结果合并成一个结果
查询语句1 union 查询语句2
1、要求多条查询语句的查询列数是一致的! 2、要求多条查询语句的查询的每一列的类型和顺序最好一致 3、union关键字默认去重,如果使用union all 可以包含重复项
2. 联合查询示例
-- 两个查询结合取并集
SELECT * FROM employees WHERE email LIKE '%a%'
UNION
SELECT * FROM employees WHERE department_id>90;
LeetCode MySQL 题目示例
题目 1212. 查询球队分数
表: Teams
+---------------+----------+
| Column Name | Type |
+---------------+----------+
| team_id | int |
| team_name | varchar |
+---------------+----------+
team_id 是该表具有唯一值的列。
表中的每一行都代表一支独立足球队。
表: Matches
+---------------+---------+
| Column Name | Type |
+---------------+---------+
| match_id | int |
| host_team | int |
| guest_team | int |
| host_goals | int |
| guest_goals | int |
+---------------+---------+
match_id 是该表具有唯一值的列。
表中的每一行都代表一场已结束的比赛。
比赛的主客队分别由它们自己的 id 表示,他们的进球由 host_goals 和 guest_goals 分别表示。
你希望在所有比赛之后计算所有球队的比分。积分奖励方式如下:
如果球队赢了比赛(即比对手进更多的球),就得 3 分。
如果双方打成平手(即,与对方得分相同),则得 1 分。
如果球队输掉了比赛(例如,比对手少进球),就 不得分 。
编写解决方案,以找出每个队的 team_id,team_name 和 num_points。
返回的结果根据 num_points 降序排序,如果有两队积分相同,那么这两队按 team_id 升序排序。
返回结果格式如下。
示例 1:
输入:
Teams table:
+-----------+--------------+
| team_id | team_name |
+-----------+--------------+
| 10 | Leetcode FC |
| 20 | NewYork FC |
| 30 | Atlanta FC |
| 40 | Chicago FC |
| 50 | Toronto FC |
+-----------+--------------+
Matches table:
+------------+--------------+---------------+-------------+--------------+
| match_id | host_team | guest_team | host_goals | guest_goals |
+------------+--------------+---------------+-------------+--------------+
| 1 | 10 | 20 | 3 | 0 |
| 2 | 30 | 10 | 2 | 2 |
| 3 | 10 | 50 | 5 | 1 |
| 4 | 20 | 30 | 1 | 0 |
| 5 | 50 | 30 | 1 | 0 |
+------------+--------------+---------------+-------------+--------------+
输出:
+------------+--------------+---------------+
| team_id | team_name | num_points |
+------------+--------------+---------------+
| 10 | Leetcode FC | 7 |
| 20 | NewYork FC | 3 |
| 50 | Toronto FC | 3 |
| 30 | Atlanta FC | 1 |
| 40 | Chicago FC | 0 |
+------------+--------------+---------------+
解决方案
# 1. 分开计算球队作为主场和客场得分情况,
# 2. 合并结果, 分组得到分数结果
# 3. 排序属性结果.
select t.team_id, t.team_name, ifnull(sum(r.score), 0) num_points from HTeams t
left join (
select host_team team_id, sum(if(host_goals > guest_goals, 3, if(host_goals = guest_goals, 1, 0))) score from HMatches group by host_team
union all
select guest_team team_id, sum(if(guest_goals > host_goals, 3, if(host_goals = guest_goals, 1, 0))) score from HMatches group by guest_team
) as r on t.team_id = r.team_id
group by r.team_id order by num_points desc, t.team_id