MySQL表的增删查改

表的增删查改,即CRUD:Create(创建),Retrieve(读取),Update(更新),Delete(删除).

Create

语法:

sql 复制代码
INSERT [INTO] table_name 
	[(column [, column] ...)] 
	VALUES (value_list) [, (value_list)] ...
	value_list: value, [, value] ...

先创建一个表用于测试插入:

sql 复制代码
CREATE TABLE students (
id INT UNSIGNED PRIMARY KEY AUTO_INCREMENT,
sn INT NOT NULL UNIQUE COMMENT '学号',
name VARCHAR(20) NOT NULL,
qq VARCHAR(20)
);

全列插入

默认插入语法就是全列插入:

sql 复制代码
mysql> insert into students values(1,23101,'刘玄德',8888);
Query OK, 1 row affected (0.01 sec)

mysql> insert students values(2,23102,'关云长',null);
Query OK, 1 row affected (0.00 sec)

mysql> select * from students;
+----+-------+-----------+------+
| id | sn    | name      | qq   |
+----+-------+-----------+------+
|  1 | 23101 | 刘玄德    | 8888 |
|  2 | 23102 | 关云长    | NULL |
+----+-------+-----------+------+
2 rows in set (0.00 sec)

可以看到我们可以省略into。

多行插入

我们可以,分隔来进行多行插入:

sql 复制代码
mysql> insert into students values(3,23103,'张翼德',null),(4,23104,'曹孟德',null);
Query OK, 2 rows affected (0.01 sec)
Records: 2  Duplicates: 0  Warnings: 0

mysql> select * from students;
+----+-------+-----------+------+
| id | sn    | name      | qq   |
+----+-------+-----------+------+
|  1 | 23101 | 刘玄德    | 8888 |
|  2 | 23102 | 关云长    | NULL |
|  3 | 23103 | 张翼德    | NULL |
|  4 | 23104 | 曹孟德    | NULL |
+----+-------+-----------+------+
4 rows in set (0.00 sec)

指定列插入

此外,我们还能只插入指定列而非全列插入:

插入否则更新

由于 主键 或者 唯一键 对应的值已经存在而导致插入失败.

  • 主键冲突:
sql 复制代码
mysql> insert into students values(3,23106,'孙悟空',null);
ERROR 1062 (23000): Duplicate entry '3' for key 'students.PRIMARY'
  • 唯一键冲突:
sql 复制代码
mysql> insert into students values(6,23103,'猪悟能',null);
ERROR 1062 (23000): Duplicate entry '23103' for key 'students.sn'

可以选择性的进行同步更新操作语法:

sql 复制代码
INSERT ... ON DUPLICATE KEY UPDATE 
column = value [, column = value] ... 

着意味着发生了唯一型冲突后才会执行UPDATE之后的语句:

  1. 无冲突,影响行数1
sql 复制代码
mysql> insert into students values(6,23106,'沙悟净',null) on duplicate key update id=10;
Query OK, 1 row affected (0.02 sec)

mysql> select * from students;
+----+-------+-----------+------+
| id | sn    | name      | qq   |
+----+-------+-----------+------+
|  1 | 23101 | 刘玄德    | 8888 |
|  2 | 23102 | 关云长    | NULL |
|  3 | 23103 | 张翼德    | NULL |
|  4 | 23104 | 曹孟德    | NULL |
|  5 | 23105 | 孙仲谋    | NULL |
|  6 | 23106 | 沙悟净    | NULL |
+----+-------+-----------+------+
6 rows in set (0.00 sec)
  1. 有冲突,且插入值与原值不同,影响行数2
sql 复制代码
mysql> insert into students values(6,23106,'沙悟净',null) on duplicate key update id=10;
Query OK, 2 rows affected (0.01 sec)

mysql> select * from students;
+----+-------+-----------+------+
| id | sn    | name      | qq   |
+----+-------+-----------+------+
|  1 | 23101 | 刘玄德    | 8888 |
|  2 | 23102 | 关云长    | NULL |
|  3 | 23103 | 张翼德    | NULL |
|  4 | 23104 | 曹孟德    | NULL |
|  5 | 23105 | 孙仲谋    | NULL |
| 10 | 23106 | 沙悟净    | NULL |
+----+-------+-----------+------+
6 rows in set (0.00 sec)
  1. 有冲突,且插入值与原值相同,影响行数0
sql 复制代码
mysql> insert into students values(6,23106,'沙悟净',null) on duplicate key update id=10;
Query OK, 0 rows affected (0.01 sec)

mysql> select * from students;
+----+-------+-----------+------+
| id | sn    | name      | qq   |
+----+-------+-----------+------+
|  1 | 23101 | 刘玄德    | 8888 |
|  2 | 23102 | 关云长    | NULL |
|  3 | 23103 | 张翼德    | NULL |
|  4 | 23104 | 曹孟德    | NULL |
|  5 | 23105 | 孙仲谋    | NULL |
| 10 | 23106 | 沙悟净    | NULL |
+----+-------+-----------+------+
6 rows in set (0.00 sec)

替换

我们可以直接用replace代替insert,如果没有冲突就是直接插入,如果发生了冲突就会删除然后插入:

sql 复制代码
mysql> replace into students(sn,name) values(23106,'唐玄奘');
Query OK, 2 rows affected (0.01 sec)

mysql> select * from students;
+----+-------+-----------+------+
| id | sn    | name      | qq   |
+----+-------+-----------+------+
|  1 | 23101 | 刘玄德    | 8888 |
|  2 | 23102 | 关云长    | NULL |
|  3 | 23103 | 张翼德    | NULL |
|  4 | 23104 | 曹孟德    | NULL |
|  5 | 23105 | 孙仲谋    | NULL |
| 11 | 23106 | 唐玄奘    | NULL |
+----+-------+-----------+------+
6 rows in set (0.00 sec)

mysql> replace into students(sn,name) values(23107,'李世民');
Query OK, 1 row affected (0.00 sec)

mysql> select * from students;
+----+-------+-----------+------+
| id | sn    | name      | qq   |
+----+-------+-----------+------+
|  1 | 23101 | 刘玄德    | 8888 |
|  2 | 23102 | 关云长    | NULL |
|  3 | 23103 | 张翼德    | NULL |
|  4 | 23104 | 曹孟德    | NULL |
|  5 | 23105 | 孙仲谋    | NULL |
| 11 | 23106 | 唐玄奘    | NULL |
| 12 | 23107 | 李世民    | NULL |
+----+-------+-----------+------+
7 rows in set (0.00 sec)

Retrieve

语法:

sql 复制代码
SELECT  
	[DISTINCT] {* | {column [, column] ...}  
	[FROM table_name] 
	[WHERE ...] 
	[ORDER BY column [ASC | DESC], ...] 
	LIMIT ... 

我们还是先创建表用于测试案例:

sql 复制代码
mysql> CREATE TABLE exam_result ( 
    -> id INT UNSIGNED PRIMARY KEY AUTO_INCREMENT, 
    -> name VARCHAR(20) NOT NULL COMMENT '同学姓名', 
    -> chinese float DEFAULT 0.0 COMMENT '语文成绩', 
    -> math float DEFAULT 0.0 COMMENT '数学成绩', 
    -> english float DEFAULT 0.0 COMMENT '英语成绩' 
    -> ); 
Query OK, 0 rows affected (0.04 sec)

再插入部分数据:

sql 复制代码
mysql> INSERT INTO exam_result (name, chinese, math, english) VALUES 
    -> ('唐三藏', 67, 98, 56), 
    -> ('孙悟空', 87, 78, 77), 
    -> ('猪悟能', 88, 98, 90), 
    -> ('曹孟德', 82, 84, 67), 
    -> ('刘玄德', 55, 85, 45), 
    -> ('孙权', 70, 73, 78), 
    -> ('宋公明', 75, 65, 30); 
Query OK, 7 rows affected (0.01 sec)
Records: 7  Duplicates: 0  Warnings: 0

SElECT列

全列查询

全列查询我们用的非常多了:

这里*就是全列查询。

但通常来说不建议使用全列查询

  1. 查询的列越多,意味着需要传输的数据量越大;
  2. 可能会影响到索引的使用。

指定列查询

我们可以选定想要查询的列:

而且我们无需遵循原表顺序,甚至可以:

查询字段为表达式

我们可以在select后面加上一些表达式:

sql 复制代码
mysql> select name,id+10,1,1+1 from exam_result;
+-----------+-------+---+-----+
| name      | id+10 | 1 | 1+1 |
+-----------+-------+---+-----+
| 唐三藏    |    11 | 1 |   2 |
| 孙悟空    |    12 | 1 |   2 |
| 猪悟能    |    13 | 1 |   2 |
| 曹孟德    |    14 | 1 |   2 |
| 刘玄德    |    15 | 1 |   2 |
| 孙权      |    16 | 1 |   2 |
| 宋公明    |    17 | 1 |   2 |
+-----------+-------+---+-----+
7 rows in set (0.00 sec)

为查询结果指定别名

在查询列后加as newcolname就能给列指定别名,as还可以省略。

此外不仅能给原列指定别名,还能给表达式指定别名:

sql 复制代码
mysql> select name as 姓名,id ID,chinese+english+math 总分 from exam_result;
+-----------+----+--------+
| 姓名      | ID | 总分   |
+-----------+----+--------+
| 唐三藏    |  1 |    221 |
| 孙悟空    |  2 |    242 |
| 猪悟能    |  3 |    276 |
| 曹孟德    |  4 |    233 |
| 刘玄德    |  5 |    185 |
| 孙权      |  6 |    221 |
| 宋公明    |  7 |    170 |
+-----------+----+--------+
7 rows in set (0.00 sec)

结果去重

sql 复制代码
mysql> select math from exam_result;
+------+
| math |
+------+
|   98 |
|   78 |
|   98 |
|   84 |
|   85 |
|   73 |
|   65 |
+------+
7 rows in set (0.00 sec)

可以看到98分重复了,我们可以加上distinct关键字去重:

sql 复制代码
mysql> select distinct math from exam_result;
+------+
| math |
+------+
|   98 |
|   78 |
|   84 |
|   85 |
|   73 |
|   65 |
+------+
6 rows in set (0.05 sec)

WHERE条件

我们可以在查询时跟上where和比较运算符.

比较运算符:

运算符 说明
>, >=, <, <= 大于,大于等于,小于,小于等于
= 等于,NULL 不安全,例如 NULL = NULL 的结果是 NULL
<=> 等于,NULL 安全,例如 NULL <=> NULL 的结果是 TRUE(1)
!=, <> 不等于
BETWEEN a0 AND a1 范围匹配,[a0, a1],如果 a0 <= value <= a1,返回 TRUE(1)
IN (option, ...) 如果是 option 中的任意一个,返回 TRUE(1)
IS NULL NULL
IS NOT NULL 不是 NULL
LIKE 模糊匹配。% 表示任意多个(包括 0 个)任意字符;_ 表示任意一个字符

逻辑运算符:

运算符 说明
AND 多个条件必须都为 TRUE(1),结果才是 TRUE(1)
OR 任意一个条件为 TRUE(1),结果为 TRUE(1)
NOT 条件为 TRUE(1),结果为 FALSE(0)

=和!=这些运算对NULL运算是不安全的,所以更常用IS NULL来进行判空。

我们来做一些尝试:

  1. 英语不及格的同学及英语成绩 ( < 60 )

  2. 语文成绩在 [80, 90] 分的同学及语文成绩

  3. 数学成绩是 58 或者 59 或者 98 或者 99 分的同学及数学成绩

  4. 姓孙的同学 及 孙某同学

  5. 语文成绩好于英语成绩的同学

  6. 总分在 200 分以下的同学

    这时候就有一个问题,我们where后面能不能用总分这个别名?

    答案是不能,原因很简单,我们分析一下查询的顺序:

    我们查询表首先得要找到表的位置,其次根据条件筛选数据,最后才是选择列。因此where还不知道总分这个别名。

  7. 语文成绩 > 80 并且不姓孙的同学

  8. 孙某同学,否则要求总成绩 > 200 并且 语文成绩 < 数学成绩 并且 英语成绩 > 80

    9.NULL查询

结果排序

我们还能对结果进行排序:

sql 复制代码
-- ASC(Ascending) 为升序(从小到大) 
-- DESC(Descending) 为降序(从大到小) 
-- 默认为 ASC 

SELECT ... FROM table_name [WHERE ...]  
	ORDER BY column [ASC|DESC], [...]; 

注意:没有 ORDER BY 子句的查询,返回的顺序是未定义的,永远不要依赖这个顺序,即使你是有序插入的。

使用示例:

  1. 同学及数学成绩,按数学成绩升序显示
  2. 同学及 qq 号,按 qq 号排序显示

    着意味着NULL视为最小的值。
  3. 查询同学各门成绩,依次按 数学降序,英语升序,语文升序的方式显示
  4. 查询同学及总分,由高到低

    注意到我们这时又可以使用总分这个别名了。这是因为我们都是在筛选之后再进行排序的,技术上来说我们可以在筛选前排序,但这是比较浪费的。因此order by执行顺序在重命名后。
  5. 查询姓孙的同学或者姓曹的同学数学成绩,结果按数学成绩由高到低显示

筛选分页结果

有时候查询结果太多,我们可以用limit关键字进行分页:

sql 复制代码
-- 起始下标为 0 -- 从 0 开始,筛选 n 条结果
SELECT ... FROM table_name [WHERE ...] [ORDER BY ...] LIMIT n;

-- 从 s 开始,筛选 n 条结果 
SELECT ... FROM table_name [WHERE ...] [ORDER BY ...] LIMIT s, n
; 

-- 从 s 开始,筛选 n 条结果,比第二种用法更明确,建议使用 
SELECT ... FROM table_name [WHERE ...] [ORDER BY ...] LIMIT n OFFSET s; 

如:

sql 复制代码
mysql> select * from exam_result limit 3;
+----+-----------+---------+------+---------+
| id | name      | chinese | math | english |
+----+-----------+---------+------+---------+
|  1 | 唐三藏    |      67 |   98 |      56 |
|  2 | 孙悟空    |      87 |   78 |      77 |
|  3 | 猪悟能    |      88 |   98 |      90 |
+----+-----------+---------+------+---------+
3 rows in set (0.00 sec)

mysql> select * from exam_result limit 1,3;
+----+-----------+---------+------+---------+
| id | name      | chinese | math | english |
+----+-----------+---------+------+---------+
|  2 | 孙悟空    |      87 |   78 |      77 |
|  3 | 猪悟能    |      88 |   98 |      90 |
|  4 | 曹孟德    |      82 |   84 |      67 |
+----+-----------+---------+------+---------+
3 rows in set (0.00 sec)

mysql> select * from exam_result limit 3 offset 1;
+----+-----------+---------+------+---------+
| id | name      | chinese | math | english |
+----+-----------+---------+------+---------+
|  2 | 孙悟空    |      87 |   78 |      77 |
|  3 | 猪悟能    |      88 |   98 |      90 |
|  4 | 曹孟德    |      82 |   84 |      67 |
+----+-----------+---------+------+---------+
3 rows in set (0.00 sec)

Update

语法:

sql 复制代码
UPDATE table_name SET column = expr [, column = expr ...] 
[WHERE ...] [ORDER BY ...] [LIMIT ...] 

可以看到我们更新是针对列更新的,因此最好加上where否则会整列更新。

示例:

  1. 将孙悟空同学的数学成绩变更为 80 分
  2. 将曹孟德同学的数学成绩变更为 60 分,语文成绩变更为 70 分
  3. 将总成绩倒数前三的 3 位同学的数学成绩加上 30 分
  4. 将所有同学的语文成绩更新为原来的 2 倍
sql 复制代码
mysql> select name,chinese from exam_result;
+-----------+---------+
| name      | chinese |
+-----------+---------+
| 唐三藏    |      67 |
| 孙悟空    |      87 |
| 猪悟能    |      88 |
| 曹孟德    |      70 |
| 刘玄德    |      55 |
| 孙权      |      70 |
| 宋公明    |      75 |
+-----------+---------+
7 rows in set (0.00 sec)

mysql> update exam_result set chinese=2*chinese;
Query OK, 7 rows affected (0.01 sec)
Rows matched: 7  Changed: 7  Warnings: 0

mysql> select name,chinese from exam_result;
+-----------+---------+
| name      | chinese |
+-----------+---------+
| 唐三藏    |     134 |
| 孙悟空    |     174 |
| 猪悟能    |     176 |
| 曹孟德    |     140 |
| 刘玄德    |     110 |
| 孙权      |     140 |
| 宋公明    |     150 |
+-----------+---------+
7 rows in set (0.00 sec)

Delete

删除数据

语法:

sql 复制代码
DELETE FROM  table_name [WHERE ...] [ORDER BY ...] [LIMIT ...] 

示例:

  1. 删除孙悟空同学的考试成绩
  2. 删除整张表数据
    我们先准备一个测试用的表:
sql 复制代码
mysql> CREATE TABLE for_delete ( 
    -> id INT PRIMARY KEY AUTO_INCREMENT, 
    -> name VARCHAR(20) 
    -> ); 
Query OK, 0 rows affected (0.06 sec)

mysql> INSERT INTO for_delete (name) VALUES ('A'), ('B'), ('C'); 
Query OK, 3 rows affected (0.01 sec)
Records: 3  Duplicates: 0  Warnings: 0

mysql> SELECT * FROM for_delete;
+----+------+
| id | name |
+----+------+
|  1 | A    |
|  2 | B    |
|  3 | C    |
+----+------+
3 rows in set (0.00 sec)

删除整张表:

注意此时只是删除了数据,表的结构在,我们可以看看创建语句:

可以看到自增长的值为4,这意味着我们再插入数据也是从4开始增长:

截断表

语法:

sql 复制代码
TRUNCATE [TABLE] table_name 

注意:这个操作慎用

  1. 只能对整表操作,不能像 DELETE 一样针对部分数据操作;
  2. 实际上 MySQL 不对数据操作,所以比 DELETE 更快,但是TRUNCATE在删除数据的时候,并不经过真正的事务,所以无法回滚
  3. 会重置 AUTO_INCREMENT 项

我们先准备测试用例:

截断表:

此外他还会将自增长的数值清零:

插入查询结果

我们可以将查询结果直接插入到表中,语法:

sql 复制代码
INSERT INTO table_name [(column [, column ...])] SELECT ... 

例如:删除表中的的重复复记录,重复的数据只能有一份

我们先创建测试用表:

sql 复制代码
mysql> CREATE TABLE duplicate_table (id int, name varchar(20)); 
Query OK, 0 rows affected (0.04 sec)

mysql> INSERT INTO duplicate_table VALUES 
    -> (100, 'aaa'), 
    -> (100, 'aaa'), 
    -> (200, 'bbb'), 
    -> (200, 'bbb'), 
    -> (200, 'bbb'), 
    -> (300, 'ccc'); 
Query OK, 6 rows affected (0.00 sec)
Records: 6  Duplicates: 0  Warnings: 0

mysql> select * from duplicate_table;
+------+------+
| id   | name |
+------+------+
|  100 | aaa  |
|  100 | aaa  |
|  200 | bbb  |
|  200 | bbb  |
|  200 | bbb  |
|  300 | ccc  |
+------+------+
6 rows in set (0.00 sec)

具体实现思路是新建一个相同的表结构,然后将旧表数据去重后插入新表,最后对两表重命名:

先创建表结构,拷贝创建语句即可:

sql 复制代码
mysql> show create table duplicate_table \G
*************************** 1. row ***************************
       Table: duplicate_table
Create Table: CREATE TABLE `duplicate_table` (
  `id` int DEFAULT NULL,
  `name` varchar(20) COLLATE utf8mb4_unicode_ci DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
1 row in set (0.00 sec)

mysql> CREATE TABLE `new_duplicate_table` (
    ->   `id` int DEFAULT NULL,
    ->   `name` varchar(20) COLLATE utf8mb4_unicode_ci DEFAULT NULL
    -> ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
    -> ;
Query OK, 0 rows affected (0.05 sec)

或者可以用like语句:

sql 复制代码
mysql> drop table new_duplicate_table;
Query OK, 0 rows affected (0.03 sec)

mysql> create table no_duplicate_table like duplicate_table;
Query OK, 0 rows affected (0.04 sec)

然后插入去重后数据:

sql 复制代码
mysql> insert into no_duplicate_table select distinct * from duplicate_table;
Query OK, 3 rows affected (0.01 sec)
Records: 3  Duplicates: 0  Warnings: 0

mysql> select * from no_duplicate_table;
+------+------+
| id   | name |
+------+------+
|  100 | aaa  |
|  200 | bbb  |
|  300 | ccc  |
+------+------+
3 rows in set (0.00 sec)

最后通过重命名实现原子去重操作:

sql 复制代码
mysql> rename table duplicate_table to old_duplicate_table, no_duplicate_table to duplicate_table;
Query OK, 0 rows affected (0.06 sec)

mysql> select * from duplicate_table;
+------+------+
| id   | name |
+------+------+
|  100 | aaa  |
|  200 | bbb  |
|  300 | ccc  |
+------+------+
3 rows in set (0.00 sec)

聚合函数

有时候我们需要对查询的数据做一定统计,这时候就需要用到聚合函数:

函数 说明
COUNT([DISTINCT] expr) 返回查询到的数据的数量
SUM([DISTINCT] expr) 返回查询到的数据的总和,非数字类型无意义
AVG([DISTINCT] expr) 返回查询到的数据的平均值,非数字类型无意义
MAX([DISTINCT] expr) 返回查询到的数据的最大值,非数字类型无意义
MIN([DISTINCT] expr) 返回查询到的数据的最小值,非数字类型无意义
  1. 统计班级有多少名同学:
  2. 统计班级收集的 qq 号有多少

    这是因为null不计入统计:
  3. 统计本次考试的数学成绩分数个数

还可以统计去重后的数据:

  1. 统计数学成绩总分

    还可以统计数学不及格的数学总分:
  2. 统计平均总分
  3. 返回英语最高分
  4. 返回 > 70 分以上的数学最低分

SQL执行顺序

  1. FROM → 定位数据源表
  2. WHERE → 分组前过滤行(只保留符合条件的行,不能用聚合函数)
  3. GROUP BY → 对过滤后的行分组
  4. SELECT → 计算聚合函数、筛选要显示的字段
  5. HAVING → 分组后过滤分组(只能用分组字段 / 聚合函数)
  6. ORDER BY → 对最终结果排序
  7. LIMIT → 限制返回的行数

SQL查询中各个关键字的执行先后顺序 from > on> join > where > group by > with > having > select> distinct > order by > limit

group by子句的使用

在select中使用group by 子句可以对指定列进行分组查询

sql 复制代码
select column1, column2, .. from table group by column;

我们要明确分组查询的目的是使用聚合函数。

我们先准备一份信息数据

数据基本结构:

sql 复制代码
mysql> use scott;
Database changed
mysql> show tables;
+-----------------+
| Tables_in_scott |
+-----------------+
| dept            |
| emp             |
| salgrade        |
+-----------------+
3 rows in set (0.00 sec)

mysql> desc dept;
+--------+--------------------------+------+-----+---------+-------+
| Field  | Type                     | Null | Key | Default | Extra |
+--------+--------------------------+------+-----+---------+-------+
| deptno | int(2) unsigned zerofill | NO   |     | NULL    |       |
| dname  | varchar(14)              | YES  |     | NULL    |       |
| loc    | varchar(13)              | YES  |     | NULL    |       |
+--------+--------------------------+------+-----+---------+-------+
3 rows in set (0.00 sec)

mysql> desc emp;
+----------+--------------------------+------+-----+---------+-------+
| Field    | Type                     | Null | Key | Default | Extra |
+----------+--------------------------+------+-----+---------+-------+
| empno    | int(6) unsigned zerofill | NO   |     | NULL    |       |
| ename    | varchar(10)              | YES  |     | NULL    |       |
| job      | varchar(9)               | YES  |     | NULL    |       |
| mgr      | int(4) unsigned zerofill | YES  |     | NULL    |       |
| hiredate | datetime                 | YES  |     | NULL    |       |
| sal      | decimal(7,2)             | YES  |     | NULL    |       |
| comm     | decimal(7,2)             | YES  |     | NULL    |       |
| deptno   | int(2) unsigned zerofill | YES  |     | NULL    |       |
+----------+--------------------------+------+-----+---------+-------+
8 rows in set (0.00 sec)

mysql> desc salgrade;
+-------+------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+------+------+-----+---------+-------+
| grade | int  | YES  |     | NULL    |       |
| losal | int  | YES  |     | NULL    |       |
| hisal | int  | YES  |     | NULL    |       |
+-------+------+------+-----+---------+-------+
3 rows in set (0.00 sec)
  1. 显示每个部门的平均工资和最高工资

    分组针对聚合函数,原则上处理分组的元素和聚合函数,其他元素都不能select出来:
  2. 显示每个部门的每种岗位的平均工资和最低工资
  3. 显示平均工资低于2000的部门和它的平均工资

    having和where类似,但是having是对分组之后结果进行筛选。

OJ

  1. 批量插入数据
sql 复制代码
insert into actor values(1,'PENELOPE','GUINESS','2006-02-15 12:34:33'),
(2,'NICK','WAHLBERG','2006-02-15 12:34:33');
  1. 找出所有员工当前薪水salary情况
sql 复制代码
select distinct salary  from salaries order by salary desc;
  1. 查找最晚入职员工的所有信息
sql 复制代码
select * from employees order by hire_date desc limit 1;
  1. 查找入职员工时间排名倒数第三的员工所有信息
sql 复制代码
select * from employees where hire_date=(
    select distinct hire_date from employees
    order by hire_date desc limit 2,1
);
  1. 查找薪水记录超过15条的员工号emp_no以及其对应的记录次数t
sql 复制代码
select emp_no,count(1) from salaries group by emp_no having count(1)>15;
  1. 从titles表获取按照title进行分组
sql 复制代码
select title,count(1) t from titles group by title having t>1; 
  1. 查找重复的电子邮箱
sql 复制代码
select Email from Person group by email having count(1)>1;
  1. 大的国家
sql 复制代码
select name,population,area from World where population>=25000000 or
area >=3000000;
相关推荐
yangSnowy2 小时前
Redis数据类型
数据库·redis·wpf
海雅达手持终端PDA2 小时前
海雅达Model 10X工业平板赋能MES系统全场景落地应用方案
android·物联网·硬件工程·能源·健康医疗·制造·平板
@我不是大鹏2 小时前
3、Spring AI Alibaba(SAA)零基础速通实战之Ollama私有化部署和对接本地大模型
数据库·人工智能·spring
Linging_242 小时前
PGSQL与Mysql对比学习
数据库·学习·mysql·postgresql
Anarkh_Lee2 小时前
【免费开源】MCP 数据库万能连接器:用自然语言查询和分析数据
数据库·开源·ai编程·claude·自然语言·mcp·cherry studio
Getgit2 小时前
mysql批量更新语句
java·数据库·mysql·udp·eclipse
普马萨特2 小时前
如何从安卓系统中获取扫描到的 Wi‑Fi 的 MAC 地址和 RSSI?
android·macos
alex18012 小时前
nginx配置图片静态路由
数据库·nginx·postgresql
明天…ling2 小时前
sql注入(1-10关)
java·数据库·sql