MySQL打卡练习-5
练习一:行转列
问题描述
假设有如下比赛结果
+--------------+-----------+
| cdate | result |
+--------------+-----------+
| 2021-01-01 | 胜 |
| 2021-01-01 | 负 |
| 2021-01-03 | 胜 |
| 2021-01-03 | 负 |
| 2021-01-01 | 胜 |
| 2021-01-03 | 负 |
+------------+-----------+
请使用 SQL 将比赛结果转换为如下形式:
+--------------+-----+-----|
| 比赛日期 | 胜 | 负 |
+--------------+-----------+
| 2021-01-01 | 2 | 1 |
| 2021-01-03 | 1 | 2 |
+------------+-----------+
解题答案
创建数据
CREATE TABLE compete
(
c_date DATE,
result CHAR
);
INSERT INTO compete
VALUES (20210101, "胜"),
(20210101, "负"),
(20210103, "胜"),
(20210103, "负"),
(20210101, "胜"),
(20210103, "负");
解题答案
SELECT c_date as "比赛日期",
COUNT(IF(result = "胜", result, NULL)) as "胜",
COUNT(IF(result = "负", result, NULL)) as "负"
FROM compete
GROUP BY c_date;
练习二:列转行
问题描述
假设有如下比赛结果
+--------------+-----+-----|
| 比赛日期 | 胜 | 负 |
+--------------+-----------+
| 2021-01-01 | 2 | 1 |
| 2021-01-03 | 1 | 2 |
+------------+-----------+
请使用 SQL 将比赛结果转换为如下形式:
+--------------+-----------+
| cdate | result |
+--------------+-----------+
| 2021-01-01 | 胜 |
| 2021-01-01 | 负 |
| 2021-01-03 | 胜 |
| 2021-01-03 | 负 |
| 2021-01-01 | 胜 |
| 2021-01-03 | 负 |
+------------+-----------+
解题答案
创建数据
CREATE TABLE compete_score
(
比赛日期 DATE,
胜 INT,
负 INT
);
INSERT INTO compete_score
VALUES ("20210101", 2, 1),
("20210103", 1, 2);
解题答案
暂无
练习三:连续登录
问题描述
有用户表行为记录表t_act_records表,包含两个字段:uid(用户ID),imp_date(日期)
- 计算2021年每个月,每个用户连续登录的最多天数
- 计算2021年每个月,连续2天都有登录的用户名单
- 计算2021年每个月,连续5天都有登录的用户数
构造表mysql如下:
DROP TABLE if EXISTS t_act_records;
CREATE TABLE t_act_records
(uid VARCHAR(20),
imp_date DATE);
INSERT INTO t_act_records VALUES('u1001', 20210101);
INSERT INTO t_act_records VALUES('u1002', 20210101);
INSERT INTO t_act_records VALUES('u1003', 20210101);
INSERT INTO t_act_records VALUES('u1003', 20210102);
INSERT INTO t_act_records VALUES('u1004', 20210101);
INSERT INTO t_act_records VALUES('u1004', 20210102);
INSERT INTO t_act_records VALUES('u1004', 20210103);
INSERT INTO t_act_records VALUES('u1004', 20210104);
INSERT INTO t_act_records VALUES('u1004', 20210105);
解题答案
解题答案
SELECT uid, imp_date, ROW_NUMBER() over (PARTITION BY uid ORDER BY imp_date) as "ranking"
FROM t_act_records;
SELECT *, DATE_SUB(imp_date, INTERVAL ranking DAY) as ds
FROM (
SELECT uid, imp_date, ROW_NUMBER() over (PARTITION BY uid ORDER BY imp_date) as "ranking"
FROM t_act_records) as test;
SELECT uid, ds, COUNT(1)
FROM (SELECT *, DATE_SUB(imp_date, INTERVAL ranking DAY) as ds
FROM (
SELECT uid, imp_date, ROW_NUMBER() over (PARTITION BY uid ORDER BY imp_date) as "ranking"
FROM t_act_records) as test) as sub_ds
GROUP BY uid, ds
;
SELECT DISTINCT uid, ds, COUNT(1)
FROM (SELECT *, DATE_SUB(imp_date, INTERVAL ranking DAY) as ds
FROM (
SELECT uid, imp_date, ROW_NUMBER() over (PARTITION BY uid ORDER BY imp_date) as "ranking"
FROM t_act_records) as test) as sub_ds
GROUP BY uid, ds
;
SELECT DISTINCT uid, ds, COUNT(1)
FROM (SELECT *, DATE_SUB(imp_date, INTERVAL ranking DAY) as ds
FROM (
SELECT uid, imp_date, ROW_NUMBER() over (PARTITION BY uid ORDER BY imp_date) as "ranking"
FROM t_act_records) as test) as sub_ds
GROUP BY uid, ds
HAVING COUNT(1) >= 3
;
SELECT DISTINCT uid, ds, COUNT(1)
FROM (SELECT *, DATE_SUB(imp_date, INTERVAL ranking DAY) as ds
FROM (
SELECT uid, imp_date, ROW_NUMBER() over (PARTITION BY uid ORDER BY imp_date) as "ranking"
FROM t_act_records) as test) as sub_ds
GROUP BY uid, ds
HAVING COUNT(1) >= 5
;
|