【教奶奶学SQL】(task6)秋招秘籍C

简介: 练习一:行转列假设有如下比赛结果

练习一:行转列

假设有如下比赛结果

+--------------+-----------+
|    cdate     |   result  |
+--------------+-----------+
|  2021-01-01  |     胜    |
|  2021-01-01  |     负    |
|  2021-01-03  |     胜    |
|  2021-01-03  |     负    |
|  2021-01-01  |     胜    |
|  2021-01-03  |     负    |
+------------+-----------+

方法一:

通过日期cdate进行分组,可以通过SUM(CASE WHEN)或者COUNT(IF)统计各天的胜负次数。

SELECT  
  cdate, 
    SUM(CASE WHEN result = '胜' then 1 else 0 end) AS '胜',
    SUM(CASE WHEN result = '负' then 1 else 0 end) AS '负'
FROM score3
GROUP BY cdate;

方法二:

# 方法二 
SELECT cdate, 
     COUNT(IF(result = '胜', true, NULL)) AS '胜',
       COUNT(IF(result = '负', true, NULL)) AS '负'
FROM score3 
GROUP BY cdate;

比赛结果转换为如下形式:

+--------------+-----+-----|
|  比赛日期     | 胜  | 负  |
+--------------+-----------+
|  2021-01-01  |  2  |  1  |
|  2021-01-03  |  1  |  2  |
+------------+-----------+

练习二:列转行

假设有如下比赛结果

+--------------+-----+-----|
|  比赛日期     | 胜  | 负  |
+--------------+-----------+
|  2021-01-01  |  2  |  1  |
|  2021-01-03  |  1  |  2  |
+------------+-----------+

将比赛结果转换为如下形式:

+--------------+-----------+
|    cdate     |   result  |
+--------------+-----------+
|  2021-01-01  |     胜    |
|  2021-01-01  |     负    |
|  2021-01-03  |     胜    |
|  2021-01-03  |     负    |
|  2021-01-01  |     胜    |
|  2021-01-03  |     负    |
+------------+-----------+

练习三:连续登录

有用户表行为记录表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);

表如图:

image.png

(1)计算2021年每个月,每个用户连续登录的最多天数

方法一:

datediff函数返回前一个日期减去后一个日期的差值(可正可负),这里的日期格式是2021-04-14这种的。

SELECT MONTH(imp_date) AS '月份',
     uid,
     min(imp_date) AS '起始日期',
     max(imp_date) AS '终止日期',
     count(*) AS '连续天数'
FROM(SELECT uid,imp_date,
      DATEDIFF(imp_date,'2020-01-01')-RANK() OVER(PARTITION BY uid 
                            ORDER BY imp_date) AS ranking
   FROM t_act_records) AS r
GROUP BY uid, MONTH(imp_date), r.ranking
ORDER BY 连续天数 DESC;

image.png

(2)计算2021年每个月,连续2天都有登录的用户名单

(3)计算2021年每个月,连续5天都有登录的用户数

练习四:hive 数据倾斜的产生原因及优化策略?

1.1 操作:image.png

1.2 原因:

1)、key分布不均匀

2)、业务数据本身的特性

3)、建表时考虑不周

4)、某些SQL语句本身就有数据倾斜

练习五:LEFT JOIN 是否可能会出现多出的行?为什么?

假设 A表有6行(关联列 name 有2行为空),B表有6行(关联列 name 有3行为空),

那么 SELECT * FROM A LEFT JOIN B on A.name = B.name 会返回多少行结果?

可以参考下图

A表的创表语句:

USE autumn;
CREATE TABLE A
(id VARCHAR(8) NOT NULL,
 name VARCHAR(8) ,
 score INTEGER);
INSERT INTO A VALUES('1', 'aaa', 90);
INSERT INTO A VALUES('2', 'bbb', 80);
INSERT INTO A VALUES('3', 'ccc', 70);
INSERT INTO A VALUES('4', 'ddd', 60);
INSERT INTO A VALUES('5', '', 90);
INSERT INTO A VALUES('6', '', 100);
SELECT * FROM A;

A表:

image.png

B表的创建语句:

CREATE TABLE B 
(id VARCHAR(8) NOT NULL,
 name VARCHAR(8) ,
 city VARCHAR(16));
INSERT INTO B VALUES('1', 'aaa', 'beijing');
INSERT INTO B VALUES('2', 'bbb', 'tianjin');
INSERT INTO B VALUES('3', 'ccc', 'chengdu');
INSERT INTO B VALUES('4', '', 'shenzhen');
INSERT INTO B VALUES('5', '', 'qingdao');
INSERT INTO B VALUES('6', '', 'guangzhou');
SELECT * FROM B;

B表:

image.png

LEFT JOIN的结果会发现,行数增加:

SELECT * 
FROM A 
LEFT JOIN B 
ON A.name = B.name;

image.png

左表关联列为NULL的行会与右表关联列为NULL的行去关联,条件就是 NULL= NULL,所以由 NULL产生的行数是左表 NULL的行数 m 乘以 右表 NULL的行数 n

总行数 = 左表的非空行数 + m * n

所以通过LEFT JOIN有可能行数增加的,最多是笛卡尔积,即两表的行数相乘。

六、找出每个部门前k大的员工

相关文章
|
SQL 关系型数据库 MySQL
【教奶奶学SQL】(task6)秋招秘籍C
练习一:行转列 假设有如下比赛结果
103 0
【教奶奶学SQL】(task6)秋招秘籍C
|
SQL Oracle 关系型数据库
【教奶奶学SQL】(task6)秋招秘籍B
练习一:行转列 假设 A B C 三位小朋友期末考试成绩如下所示:
115 0
【教奶奶学SQL】(task6)秋招秘籍B
|
SQL 数据采集 关系型数据库
【教奶奶学SQL】(task4)集合运算
集合在数学领域表示“各种各样的事物的总和”, 在数据库领域表示记录的集合. 具体来说,表、视图和查询的执行结果都是记录的集合, 其中的元素为表或者查询结果中的每一行。
235 0
【教奶奶学SQL】(task4)集合运算
|
SQL 关系型数据库 MySQL
【教奶奶学SQL】(task2)基础查询与排序
从表中选取数据时需要使用SELECT语句,也就是只从表中选出(SELECT)必要数据的意思。通过SELECT语句查询并选取出必要数据的过程称为匹配查询或查询(query)。
127 0
【教奶奶学SQL】(task2)基础查询与排序
|
SQL 存储 关系型数据库
【教奶奶学SQL】(task1)初识数据库
数据库是将大量数据保存起来,通过计算机加工而成的可以进行高效访问的数据集合。该数据集合称为数据库(Database,DB)。用来管理数据库的计算机系统称为数据库管理系统(Database Management System,DBMS)。
139 0
【教奶奶学SQL】(task1)初识数据库
|
SQL
【教奶奶学SQL】(task6)秋招秘籍A(leetcode刷题)
【leetcode】184 部门工资最高的员工 创建Employee 表,包含所有员工信息,每个员工有其对应的 Id, salary 和 department Id。 并插入数据:
145 0
【教奶奶学SQL】(task6)秋招秘籍A(leetcode刷题)
|
SQL OLAP Serverless
【教奶奶学SQL】(task5)SQL高级处理(窗口函数 | ROLLUP)
窗口函数也称为OLAP函数。OLAP 是 OnLine AnalyticalProcessing 的简称,意思是对数据库数据进行实时分析处理。 为了便于理解,称之为 窗口函数。常规的SELECT语句都是对整张表进行查询,而窗口函数可以让我们有选择的去某一部分数据进行汇总、计算和排序。
167 0
【教奶奶学SQL】(task5)SQL高级处理(窗口函数 | ROLLUP)
|
SQL 存储 关系型数据库
【教奶奶学SQL】(task3)复杂查询(视图 | 子查询 | 谓词 | Case)
单从表面上看起来这个语句是和正常的从数据表中查询数据是完全相同的,但其实我们操作的是一个视图。所以从SQL的角度来说操作视图与操作表看起来是完全相同的,那么为什么还会有视图的存在呢?视图到底是什么?视图与表有什么不同呢?
278 0
【教奶奶学SQL】(task3)复杂查询(视图 | 子查询 | 谓词 | Case)
|
SQL 存储 关系型数据库
【教奶奶学SQL】(task1)初识数据库
数据库是将大量数据保存起来,通过计算机加工而成的可以进行高效访问的数据集合。该数据集合称为数据库(Database,DB)。用来管理数据库的计算机系统称为数据库管理系统(Database Management System,DBMS)。
197 0
【教奶奶学SQL】(task1)初识数据库
|
SQL 数据采集 关系型数据库
【教奶奶学SQL】(task4)集合运算
集合在数学领域表示“各种各样的事物的总和”, 在数据库领域表示记录的集合. 具体来说,表、视图和查询的执行结果都是记录的集合, 其中的元素为表或者查询结果中的每一行。
150 0
【教奶奶学SQL】(task4)集合运算