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

我发现这个好像是用来描述事务的

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
服务器srun: error: b3307r7n8: task 14: out of memory 是一个错误的提示信息,表明服务器运行时遇到了内存不足的问题。 这个问题通常出现在服务器上运行的某个任务尝试使用超出其可用内存范围的内存资源时。在这种情况下,服务器会中断该任务,并向用户返回该错误信息。 解决这个问题的方法可以有以下几种: 1. 检查代码:首先需要检查任务的代码,特别是是否存在内存泄漏的情况。内存泄漏指的是程序在使用完内存资源后没有及时释放,导致内存占用增加。修复内存泄漏问题可以减少内存占用,从而避免出现内存不足的情况。 2. 调整资源分配:可以通过调整服务器上各个任务的资源分配来解决内存不足的问题。例如,可以分配更多的内存给该任务,这样能够满足任务对内存的需求。但需要谨慎调整,避免给该任务分配过多资源而导致其他任务无法正常运行。 3. 优化算法:如果任务需要使用大量内存,可以尝试优化算法,减少内存占用。通过合理设计算法,可以将任务的内存使用降低到一个可接受的范围内。 4. 增加服务器内存:如果以上方法无法解决问题,可以考虑增加服务器的内存容量。通过增加内存,可以满足任务对内存资源的需求,避免内存不足的问题再次出现。 综上所述,服务器srun: error: b3307r7n8: task 14: out of memory 是由于任务尝试使用超出其可用内存范围的内存资源而导致的错误。可以通过检查代码、调整资源分配、优化算法和增加服务器内存等方法来解决这个问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值