Task06:秋招秘籍 B
教程地址
https://github.com/datawhalechina/wonderful-sql
https://gitee.com/datawhalechina/wonderful-sql
1. 行转列
建表
mysql> DROP TABLE IF EXISTS exercise;
Query OK, 0 rows affected (0.02 sec)
mysql> CREATE TABLE IF NOT EXISTS exercise
-> ( index_id INTEGER PRIMARY KEY,
-> name VARCHAR(5),
-> subject VARCHAR(10),
-> score INTEGER
-> );
Query OK, 0 rows affected (0.04 sec)
mysql> INSERT INTO exercise VALUES
-> (1, 'A', 'chinese', 99),
-> (2, 'A', 'math', 98),
-> (3, 'A', 'english', 97),
-> (4, 'B', 'chinese', 92),
-> (5, 'B', 'math', 91),
-> (6, 'B', 'english', 90),
-> (7, 'C', 'chinese', 88),
-> (8, 'C', 'math', 87),
-> (9, 'C', 'english', 86)
-> ;
Query OK, 9 rows affected (0.01 sec)
Records: 9 Duplicates: 0 Warnings: 0
mysql> SELECT * FROM exercise;
+----------+------+---------+-------+
| index_id | name | subject | score |
+----------+------+---------+-------+
| 1 | A | chinese | 99 |
| 2 | A | math | 98 |
| 3 | A | english | 97 |
| 4 | B | chinese | 92 |
| 5 | B | math | 91 |
| 6 | B | english | 90 |
| 7 | C | chinese | 88 |
| 8 | C | math | 87 |
| 9 | C | english | 86 |
+----------+------+---------+-------+
9 rows in set (0.01 sec)
查询
mysql> SELECT
-> name,
-> SUM(CASE WHEN subject = 'chinese' THEN score ELSE NULL END) AS chinese,
-> SUM(CASE WHEN subject = 'math' THEN score ELSE NULL END) AS math,
-> SUM(CASE WHEN subject = 'english' THEN score ELSE NULL END) AS english
-> FROM exercise
-> GROUP BY name
-> ;
+------+---------+------+---------+
| name | chinese | math | english |
+------+---------+------+---------+
| A | 99 | 98 | 97 |
| B | 92 | 91 | 90 |
| C | 88 | 87 | 86 |
+------+---------+------+---------+
3 rows in set (0.00 sec)
这个在前面教程里面有,当时没细看,现在遇到还真懵了,然后回去看
我们用 case 之后,符合条件的行是原值,不符合的是 null
然后需要使用 sum 合并为一行,这样方便在 group 之后显示
也就是,类似于分组求和符合条件的数据
2. 列转行
建表
mysql> DROP TABLE IF EXISTS exercise;
Query OK, 0 rows affected (0.04 sec)
mysql> CREATE TABLE IF NOT EXISTS exercise
-> ( index_id INTEGER PRIMARY KEY,
-> name VARCHAR(5),
-> chinese INTEGER,
-> math INTEGER,
-> english INTEGER
-> );
Query OK, 0 rows affected (0.04 sec)
mysql> INSERT INTO exercise VALUES
-> (1, 'A', 99, 98, 97),
-> (2, 'B', 92, 91, 90),
-> (3, 'C', 88, 87, 86)
-> ;
Query OK, 3 rows affected (0.01 sec)
Records: 3 Duplicates: 0 Warnings: 0
mysql> SELECT * FROM exercise;
+----------+------+---------+------+---------+
| index_id | name | chinese | math | english |
+----------+------+---------+------+---------+
| 1 | A | 99 | 98 | 97 |
| 2 | B | 92 | 91 | 90 |
| 3 | C | 88 | 87 | 86 |
+----------+------+---------+------+---------+
3 rows in set (0.00 sec)
查询
mysql> SELECT
-> *
-> FROM (
-> SELECT name, 'chinese' AS subject, chinese AS score FROM exercise
-> UNION
-> SELECT name, 'math' AS subject, math AS score FROM exercise
-> UNION
-> SELECT name, 'english' AS subject, english AS score FROM exercise
-> ) AS ori
-> ORDER BY ori.name
-> ;
+------+---------+-------+
| name | subject | score |
+------+---------+-------+
| A | chinese | 99 |
| A | math | 98 |
| A | english | 97 |
| B | chinese | 92 |
| B | math | 91 |
| B | english | 90 |
| C | chinese | 88 |
| C | math | 87 |
| C | english | 86 |
+------+---------+-------+
9 rows in set (0.00 sec)
我原本还想用的是连接,后来发现连接都是横向的
竖直的连接,果然还是要用 union
为了和结果保持一致,我们在外面套了个查询来排序
3. 谁是明星带货主播
建表
mysql> DROP TABLE IF EXISTS exercise;
Query OK, 0 rows affected (0.04 sec)
mysql> CREATE TABLE IF NOT EXISTS exercise
-> ( index_id INTEGER PRIMARY KEY,
-> anchor_name VARCHAR(5),
-> date VARCHAR(10),
-> sales INTEGER
-> );
Query OK, 0 rows affected (0.04 sec)
mysql> INSERT INTO exercise VALUES
-> (1, 'A', '20210101', 40000),
-> (2, 'B', '20210101', 80000),
-> (3, 'A', '20210102', 10000),
-> (4, 'C', '20210102', 90000),
-> (5, 'A', '20210103', 7500),
-> (6, 'C', '20210103', 80000)
-> ;
Query OK, 6 rows affected (0.02 sec)
Records: 6 Duplicates: 0 Warnings: 0
mysql> SELECT * FROM exercise;
+----------+-------------+----------+-------+
| index_id | anchor_name | date | sales |
+----------+-------------+----------+-------+
| 1 | A | 20210101 | 40000 |
| 2 | B | 20210101 | 80000 |
| 3 | A | 20210102 | 10000 |
| 4 | C | 20210102 | 90000 |
| 5 | A | 20210103 | 7500 |
| 6 | C | 20210103 | 80000 |
+----------+-------------+----------+-------+
6 rows in set (0.00 sec)
查询
mysql> SELECT
-> *
-> -- COUNT(DISTINCT anchor_name) AS cnt_anchor,
-> -- COUNT(DISTINCT date) AS cnt_date
-> FROM
-> exercise AS o2
-> WHERE sales >= 0.9 * (
-> SELECT
-> SUM(sales)
-> FROM exercise AS o1
-> WHERE o1.date = o2.date
-> GROUP BY date
-> )
-> ;
+----------+-------------+----------+-------+
| index_id | anchor_name | date | sales |
+----------+-------------+----------+-------+
| 4 | C | 20210102 | 90000 |
| 6 | C | 20210103 | 80000 |
+----------+-------------+----------+-------+
2 rows in set (0.00 sec)
mysql> SELECT
-> COUNT(DISTINCT anchor_name) AS cnt_anchor,
-> COUNT(DISTINCT date) AS cnt_date
-> FROM
-> exercise AS o2
-> WHERE sales >= 0.9 * (
-> SELECT
-> SUM(sales)
-> FROM exercise AS o1
-> WHERE o1.date = o2.date
-> GROUP BY date
-> )
-> ;
+------------+----------+
| cnt_anchor | cnt_date |
+------------+----------+
| 1 | 2 |
+------------+----------+
1 row in set (0.00 sec)
这个条件是,某主播的销售占比达到 90% 及以上
那么首先,我们要按照 date 分组,求出每天的销售总额
然后再用关联子查询,拿到占比 90% 及以上的记录
然后对主播名单去重,计数,就是明星主播
对日期进行去重,计数,就是明星主播日
4. MySQL 中如何查看sql语句的执行计划?可以看到哪些信息?
这个还真是忘记了,查了才知道是 explain
mysql> explain select * from exercise;
+----+-------------+----------+------------+------+---------------+------+---------+------+------+----------+-------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+----------+------------+------+---------------+------+---------+------+------+----------+-------+
| 1 | SIMPLE | exercise | NULL | ALL | NULL | NULL | NULL | NULL | 6 | 100.00 | NULL |
+----+-------------+----------+------------+------+---------------+------+---------+------+------+----------+-------+
1 row in set, 1 warning (0.01 sec)
5. 解释一下 SQL 数据库中 ACID 是指什么
大概知道是有原子性、一致性、持久性,还有个忘记了
原子性(Atomicity):事务中的所有操作作为一个整体像原子一样不可分割,要么全部成功,要么全部失败。
一致性(Consistency):事务的执行结果必须使数据库从一个一致性状态到另一个一致性状态。一致性状态是指:1.系统的状态满足数据的完整性约束(主码,参照完整性,check约束等) 2.系统的状态反应数据库本应描述的现实世界的真实状态,比如转账前后两个账户的金额总和应该保持不变。
隔离性(Isolation):并发执行的事务不会相互影响,其对数据库的影响和它们串行执行时一样。比如多个用户同时往一个账户转账,最后账户的结果应该和他们按先后次序转账的结果一样。
持久性(Durability):事务一旦提交,其对数据库的更新就是持久的。任何事务或系统故障都不会导致数据丢失。4
来着我之前写的博客:https://blog.csdn.net/weixin_52202311/article/details/121871789
我发现这个好像是用来描述事务的