[3] MySQL 基础 - 查询

46 阅读4分钟

基础查询

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 = '北京');

查询结果被作为供其他的查询语句使用.

连接查询

join_query.png

连接查询分类

  • 交叉连接 (笛卡尔乘积) 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种:

  1. 出现在group by后面的列
  2. 使用聚合函数的列.

查询语句的执行顺序:

select、from、where、group by、having、order by、limit

2. where和having的区别

  1. where是在分组(聚合)前对记录进行筛选,而having是在分组结束后的结果里筛选,最后返回整个sql的查询结果。
  2. 可以把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. 查询球队分数

leetcode.cn/problems/te…

表: 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