各位小伙伴们大家好,我是还在研途的小曾哥,今天主要是给大家分享一下数据库中经典查询语句(主要内容为牛客SQL入门篇) 具体链接:牛客SQL实战,带你回顾SQL的查询语句!
前言
一个完整的SELECT语句包括6个子句,其中前面的2个子句是必不可少的,其他子句可以省略。
SELECT 语句的完整格式如下:
SELECT [DISTINCT] 目标列名序列
FROM 表名或视图名
[WHERE 条件表达式]
[GROUP BY + 列名]
[HAVING + 组条件表达式]
[ORDER BY + 列名 + [ASC|DESC]序列]
基础查询
1、查询所有列
查询全体学生的记录 SELECT 学号, 姓名, 性别, 出生日期, 班号 FROM 学生表 等价于:SELECT * FROM 学生表
现在运营想要查看用户信息表中所有的数据,请你取出相应结果
SELECT * FROM user_profile
2、查询多列
例1:查询全体学生的学号与姓名。
SELECT 学号,姓名 FROM 学生表
例2:查询全体学生的学号、课程号和成绩。
SELECT 学号,课程号,成绩 FROM 成绩表
现在运营同学想要用户的设备id对应的年龄、性别和学校的数据,请你取出相应数据
SELECT device_id,gender,age,university FROM user_profile
3、查询结果去重
消除取值相同的记录 例4.在成绩表中查询有哪些学生修了课程,要求列出学生的学号。 SELECT 学号 FROM 成绩表 结果中有重复的行。 用DISTINCT关键字可以去掉结果中的重复行。 DISTINCT关键字放在SELECT词的后边、目标列名序列的前边。
SELECT DISTINCT 学号 FROM 成绩表
现在运营需要查看用户来自于哪些学校,请从用户信息表中取出学校的去重数据。
SELECT DISTINCT university FROM user_profile
4、查询结果限制返回行数
使用LIMIT限制结果集 LIMIT 子句可以被用于强制 SELECT 语句返回指定的记录数。 LIMIT接受一个或两个数字参数。参数必须是一个整数常量。 如果只给定一个参数,它表示返回最大的记录行数目。 如果给定两个参数,第一个参数指定第一个返回记录行的偏移量,第二个参数指定返回记录行的最大数目。 为了检索从某一个偏移量到记录集的结束所有的记录行,可以指定第二个参数为 -1。 初始记录行的偏移量是 0(而不是 1)。
> 例5.检索记录行 6-10
> SELECT * FROM table LIMIT 5,5
> 例6.检索记录行 11-last
> SELECT *FROM table LIMIT 10,-1
> 例7.检索前 5 个记录行
> SELECT * FROM table LIMIT 5
现在运营只需要查看前2个用户明细设备ID数据,请你从用户信息表 user_profile 中取出相应结果。
SELECT device_id FROM user_profile ORDER BY id LIMIT 2
5 、将查询后的列重新命名
语法:列名 | 表达式 [ AS ] 新列名 或:新列名=列名 | 表达式
现在你需要查看2个用户明细设备ID数据,并将列名为’user_infors_example’,,请你从用户信息表取出相应结果。
SELECT device_id AS user_infos_example FROM user_profile LIMIT 2
6 、查找后排序
对查询结果进行排序 可对查询结果进行排序。 排序子句为: ORDER BY <列名> [ASC | DESC ] [,<列名> … ] 说明:按<列名>进行升序(ASC)或降序(DESC)排序,还可以按照别名或序 号进行排序。
例9.将学生按班号的升序排序。
SELECT * FROM 学生表 ORDER BY 班号
例10.查询选修了“M01F011”号课程的学生的学号及其成绩,查询结果按成绩降序排列。
SELECT 学号,成绩 FROM 成绩表 WHERE 课程号='M01F011' ORDER BY 成绩 DESC
现在你需要查看2个用户明细设备ID数据,并将列名改为’user_infors_example’,,请你从用户信息表取出相应结果。
SELECT device_id,age FROM user_profile ORDER BY age ASC
7、查找后多列排序
现在运营想要取出用户信息表中的年龄和gpa数据,并先按照gpa升序排序,再按照年龄升序排序输出,请取出相应数据。
SELECT device_id,gpa,age FROM user_profile ORDER BY gpa ASC,age ASC
8、查找后降序排列
现在运营想要取出用户信息表中对应的数据,并先按照gpa、年龄降序排序输出,请取出相应数据。
SELECT device_id,gpa,age FROM user_profile ORDER BY gpa DESC,age DESC
操作符
9、查找学校是北大的学生信息
例12.查询所有系号是1号的班号和班名。
SELECT 班号, 班名 FROM 班级表 WHERE 系号= 1
例13.查询考试成绩有不及格的学生的学号
SELECT DISTINCT 学号 FROM 成绩表 WHERE 成绩< 60
现在运营想要筛选出所有北京大学的学生进行用户调研,请你从用户信息表中取出满足条件的数据,结果返回设备id和学校。
SELECT device_id,university FROM user_profile WHERE university= '北京大学'
10、查找年龄大于24岁的用户信息
现在运营想要针对24岁以上的用户开展分析,请你取出满足条件的用户明细数据。
SELECT device_id,gender,age,university FROM user_profile WHERE age > 24
11、查找某个年龄段的用户信息
用BETWEEN…AND和NOT BETWEEN…AND是逻辑运算符,可以用来查找属性值在或不在指定范围内的元组,其中BETWEEN后边指定范围的下限,AND后边指定范围的上限。
例14.查询所有系号在2和3之间的班号和班名。
SELECT 班号,班名 FROM 班级表 WHERE 系号 BETWEEN 2 AND 3
等价于:
SELECT 班号,班名 FROM 班级表 WHERE 系号 >=2 AND 系号<=3
现在运营想要针对20岁及以上且23岁及以下的用户开展分析,请你取出满足条件的用户明细数据。
SELECT device_id,gender,age FROM user_profile WHERE age BETWEEN 20 AND 23
12、查找除复旦大学的用户信息
确定集合 用来查找属性值属于指定集合的元组。 格式为: 列名 [NOT] IN(常量1, 常量2,…常量n) IN:当列中的值与IN中的某个常量值相等时,则结果为True,表明此记录为符合查询条件的记录。 NOT IN:当列中的值与某个常量值相等时,结果为False,表明此记录为不符合查询条件的记录。
例17.查询所有班名是“电子信息工程技术”、“电子声像”或“电子组装技术”的班号和班名
SELECT 班号, 班名 FROM 班级表 WHERE 班名 IN ('电子信息工程技术' , '电子声像‘, '电子组装技术')
例18.查询班名既不是“电子信息工程技术”、也不是“电子声像”和“电子组装技术”的班号和班名。
SELECT 班号,班名 FROM 班级表 WHERE 班名 NOT IN ('电子信息工程技术' , '电子声像‘, '电子组装技术')
现在运营想要查看除复旦大学以外的所有用户明细,请你取出相应数据
SELECT device_id,gender,age,university FROM user_profile
WHERE university NOT IN ('复旦大学')
13、用where过滤空值练习
空值(NULL)在数据库中表示不确定的值。 例如,学生选修课程后还没有考试时,这些学生有选课记录,但没有考试成绩,因此考试成绩为空值。 判断某个值是否为NULL值,不能使用普通的比较运算符。 判断取值为空的语句格式为: 列名 IS NULL 判断取值不为空的语句格式为: 列名 IS NOT NULL
例19.查询还没有考试的学生的学号和相应的课程号。
SELECT 学号,课程号 FROM 成绩表
WHERE 成绩 IS NULL
例20.查询所有已经考试了的学生的学号和课程号。
SELECT 学号,课程号 FROM 成绩 WHERE 成绩 IS NOT NULL
现在运营想要对用户的年龄分布开展分析,在分析时想要剔除没有获取到年龄的用户,请你取出所有年龄值不为空的用户明细数据。
SELECT device_id,gender,age,university FROM user_profile WHERE age IS NOT NULL
14、高级操作符练习(1)
多重条件查询 在WHERE子句中可以使用逻辑运算符AND和OR来组成多条件查询。 使用AND谓词的语法格式如下:
布尔表达式1 AND 布尔表达式2 AND … AND 布尔表达式n 只有当全部的布尔表达式均为真时,整个表达式的结果才为真,只要有一个布尔 表达式的结果为假,则整个表达式结果即为假。
使用OR谓词的语法格式如下。
布尔表达式1 OR 布尔表达式2 OR … OR 布尔表达式n
例21.查询所有系号大于1且班名以“电子 ” 开头的班号和班名。
SELECT 班号,班名 FROM 班级表
WHERE 系号>1 AND 班名 LIKE '电子%’
例22.查询11212P和11214D班所有男生的学号、姓名、性别和班号。
SELECT 学号,姓名,性别,班号 FROM 学生表
WHERE (班号= ‘ 11212P ’ OR 班号= ‘ 11214D ’) AND 性别=‘男’
现在运营想要找到男性且GPA在3.5以上的用户进行调研,请你取出相关数据。
SELECT device_id,gender,age,university,gpa FROM user_profile WHERE gender = 'male' AND gpa > 3.5
15、高级操作符练习(2)
现在运营想要找到学校为北大或GPA在3.7以上的用户进行调研,请你取出相关数据
SELECT device_id,gender,age,university,gpa FROM user_profile WHERE university='北京大学' OR gpa > 3.7
16、Where in 和Not in
现在运营想要找到学校为北大、复旦和山大的同学进行调研,请你取出相关数据。
SELECT device_id,gender,age,university,gpa FROM user_profile
WHERE university IN ('北京大学' , '复旦大学', '山东大学')
17、操作符混合运用
现在运营想要找到gpa在3.5以上的山东大学用户 或 gpa在3.8以上的复旦大学同学进行用户调研,请你取出相应数据
SELECT device_id,gender,age,university,gpa FROM user_profile
WHERE (university='山东大学'AND gpa > 3.5) OR (university='复旦大学' AND gpa > 3.8)
18、查看学校名称中含北京的用户
字符匹配 一般形式为: 列名 [NOT ] LIKE
匹配串中可包含如下四种通配符: _:匹配任意一个字符; %:匹配0个或多个字符; [ ]:匹配[ ]中的任意一个字符(若要比较的字符是连续的,则可以用连字符“-”表 达 ); [^ ]:不匹配[ ]中的任意一个字符。
例23.查询学生表中姓‘张’的学生的详细信息。
SELECT * FROM 学生表 WHERE 姓名 LIKE ‘张%’
例24.查询姓“张”且名字是3个字的学生姓名。
SELECT * FROM 学生表 WHERE 姓名 LIKE '张__’
SELECT * FROM 学生表 WHERE rtrim(姓名) LIKE '张__'
例25.查询学生表中姓‘张’、姓‘李’和姓‘刘’的学生的情况。
SELECT * FROM 学生表 WHERE 姓名 LIKE '[张李刘]%’
例26.查询学生表表中名字的第2个字为“小”或“大”的学生的姓名和学号。
SELECT 姓名,学号 FROM 学生表 WHERE 姓名 LIKE '_[小大]%'
例27.查询学生表中所有不姓“刘”的学生。
SELECT 姓名 FROM 学生 WHERE 姓名 NOT LIKE '刘%’
例28.从学生表表中查询学号的最后一位不是2、3、5的学生信息。
SELECT * FROM 学生表 WHERE 学号 LIKE '%[^235]'
高级查询
使用聚合函数汇总数据 SQL提供的统计函数有: COUNT(【Shift+8】):统计表中元组个数; COUNT([DISTINCT] <列名>):统计本列列值个数; SUM( <列名> ):计算列值总和; AVG( <列名> ):计算列值平均值; MAX( <列名> ):求列值最大值; MIN( <列名> ): 求列值最小值。 上述函数中除COUNT(【Shift+8】)外,其他函数在计算过程中均忽略NULL值。
19、查找GPA最高值
例29.统计学生总人数。
SELECT COUNT(*) FROM 学生表
例30.统计选修了课程的学生的人数。
SELECT COUNT (DISTINCT 学号) FROM 成绩表
例31.计算学号为“11214D24”的学生的考试总成绩之和。
SELECT SUM(成绩) FROM 成绩表WHERE 学号 = ‘11214D24 '
例32.计算“M01F011”课程的学生的考试平均成绩。
SELECT AVG(成绩) FROM 成绩表 WHERE 课程号 = ‘M01F011 ‘
例33.查询选修了“M01F011” 课程的最高分和最低分。
SELECT MAX(成绩) 最高分, MIN(成绩) 最低分 FROM 成绩表
WHERE 课程号 = ‘M01F011 '
想要运营想要知道复旦大学学生gpa最高值是多少,请你取出相应数据
SELECT MAX(gpa)gpa FROM user_profile WHERE university = '复旦大学'
20、计算男生人数以及平均GPA
ROUND() 函数 ROUND 函数用于把数值字段舍入为指定的小数位数。 SQL ROUND() 语法 SELECT ROUND(column_name,decimals) FROM table_name column_name 要舍入的字段 decimals 要返回的小数位数
现在运营想要看一下男性用户有多少人以及他们的平均gpa是多少,用以辅助设计相关活动,请你取出相应数据。
SELECT COUNT(gender)male_num,ROUND(AVG(gpa),1) AS avg_gpa FROM user_profile WHERE gender='male'
21、分组计算练习题
对查询结果进行分组计算 作用:可以控制计算的级别:对全表还是对一组。 目的:细化计算函数的作用对象。 分组语句的一般形式: [GROUP BY ] [HAVING ] GROUP BY子句中的分组依据列必须是表中存在的列名,不能使用AS子句指派的结果集列的别名。 带有GROUP BY 子句的SELECT语句的查询列表中只能出现分组依据列或统计函数,因为分组后每个组只返回一行结果。
例34.统计每门课程的选课人数,列出课程号和人数。
SELECT 课程号, COUNT(课程号) AS 选课人数
FROM 成绩表
GROUP BY 课程号
该语句首先对查询结果按课程号的值分组,所有具有相同课程号值的元组归为一组,然后再对每一组使用COUNT函数进行计算,求得每组的学生人数。
例35.查询每名学生的选课门数和平均成绩。
SELECT 学号,
COUNT(*) 选课门数,
AVG(成绩) 平均成绩
FROM 成绩表
GROUP BY 学号
现在运营想要对每个学校不同性别的用户活跃情况和发帖数量进行分析,请分别计算出每个学校每种性别的用户数、30天内平均活跃天数和平均发帖数量。
SELECT gender,university,COUNT(*)user_num,AVG(active_days_within_30)avg_active_days,
AVG(question_cnt)avg_quesition_cnt
FROM user_profile
GROUP BY gender,university
21、分组过滤练习题
使用HAVING HAVING子句用于对分组后的结果再进行过滤, 它的功能有点像WHERE子句,但它用于组而不是单个记录。 在HAVING子句中可以使用统计函数,但在WHERE子句中则不能。 HAVING通常与GROUP BY子句一起使用。
例36.查询学生表中人数大于等于3的班号和人数。
SELECT 班号, COUNT(*) 人数
FROM 学生表
GROUP BY 班号
HAVING COUNT(*) >= 3
例37.查询平均成绩大于等于80的学生的学号、选课门数和平均成绩。
SELECT 学号, COUNT(*) 选课门数,
AVG(成绩) 平均成绩 FROM 成绩表
GROUP BY 学号
HAVING AVG(成绩) >= 80
现在运营想查看每个学校用户的平均发贴和回帖情况,寻找低活跃度学校进行重点运营,请取出平均发贴数低于5的学校或平均回帖数小于20的学校。
select university, round(avg(question_cnt),3) as avg_question_cnt,
round(avg(answer_cnt),3) as avg_answer_cnt from user_profile
group by university
Having avg_question_cnt <5 or avg_answer_cnt <20
22、分组排序练习题
跟上题相比较,只是多了个升序排序的条件
现在运营想要查看不同大学的用户平均发帖情况,并期望结果按照平均发帖情况进行升序排列,请你取出相应数据。
select university , avg(question_cnt) as avg_quesition_cnt
from user_profile
group by university
order by avg_quesition_cnt asc;
多表查询
23、 浙江大学用户题目回答情况
根据两张表进行连接,获取用户回答情况 多表查询 - 多表连接 若一个查询同时涉及两个或两个以上的表,则称之为连接查询。 连接查询是关系数据库中最主要的查询。 连接查询包括内连接、外连接和交叉连接等。
连接查询中用于连接两个表的条件称为连接条件或连接谓词。 一般格式为:
内连接语法:
SELECT …
FROM 表名
[INNER] JOIN 被连接表
ON 连接条件
例39.查询每个学生及其班级的详细信息。
SELECT * FROM 学生表
INNER JOIN 班级表 ON 学生表.班号=班级表.班号
结果中有重复的列:班号。
例40.去掉例39中的重复列。
SELECT 学号, 姓名,班级表.班号, 班名 FROM 学生表 JOIN 班级表
ON 学生表.班号=班级表.班号
例41.查询重修学生的修课情况,要求列出学生的名字、所修课的课程号和成绩。
SELECT 姓名, 课程号, 成绩
FROM 学生表 JOIN 成绩表
ON 学生表.学号 = 成绩表.学号
WHERE 状态 = '重修'
表别名 可以为表提供别名,其格式如下: <源表名> [ AS ] <表别名> 使用别名时例41可写为如下形式:
SELECT 姓名, 课程号, 成绩
FROM 学生表 S JOIN 成绩表 g
ON S.学号 = g.学号
WHERE 状态 = ‘重修’
注:如果为表指定了别名,则查询语句中其他所有用到表名的地方都要使用别名
现在运营想要查看所有来自浙江大学的用户题目回答明细情况,请你取出相应数据
select q.device_id, question_id, result
from question_practice_detail q join user_profile u
on q.device_id = u.device_id
where university = '浙江大学';
24、统计每个学校的答过题的用户的平均答题数
本题需要注意user_profile的answer_cnt是干扰项,仅需要device_id和university的信息。 因为存在同设备的多条信息,所以平均的结果是question_practice_detail中同university的device_id数量与device_id类型的商。
运营想要找到答题积极性较弱的学校进行重点运营,请你取出每个学校的用户平均答题数量。
select university , count(q.device_id) / count(distinct q.device_id) as avg_answer_cnt
from user_profile u join question_practice_detail q
on u.device_id = q.device_id
group by u.university;
25、统计每个学校各难度的用户平均刷题数
运营想要计算一些参加了答题的不同学校、不同难度的用户平均答题量,请你写SQL取出相应数据
思路: 所需信息分布三表,因此需要三表连接 分组按照学校,难度依次即可 平均计算仍需考虑同设备不同次登录问题,需要DISTICT加以区分除数,而被除数无需DISTINCT加以区分
解题:
select university, d.difficult_level, count(q.device_id)/count(distinct q.device_id)
as avg_answer_cnt
from user_profile u
join question_practice_detail q on u.device_id = q.device_id
join question_detail d on q.question_id = d.question_id
group by university, difficult_level;
26、统计每个用户的平均刷题数
类似SQL 入门 25,但是加限制为山东大学,
可在GROUP BY前加WHERE实现 或在GROUP BY后加HAVING实现【同时GROUP BY需要增加university】
运营想要查看参加了答题的山东大学的用户在不同难度下的平均答题题目数,请取出相应数据
select university, d.difficult_level, count(q.device_id)/count(distinct q.device_id)
as avg_answer_cnt
from user_profile u
join question_practice_detail q on u.device_id = q.device_id
join question_detail d on q.question_id = d.question_id
where university = '山东大学'
group by university, difficult_level;
============================================
select university, d.difficult_level, count(q.device_id)/count(distinct q.device_id)
as avg_answer_cnt
from user_profile u
join question_practice_detail q on u.device_id = q.device_id
join question_detail d on q.question_id = d.question_id
group by university, difficult_level
having university = '山东大学';
27、查找山东大学或者性别为男生的信息
UNION(并) 使用 UNION可以实现将多个查询结果集合并为一个结果集。 图片说明 所有查询语句中列的个数和列的顺序必须相同。 所有查询语句中对应列的数据类型必须兼容。 ORDER BY语句要放在最后一个查询语句的后边。
现在运营想要分别查看学校为山东大学或者性别为男性的用户的device_id、gender、age和gpa数据,请取出相应结果,结果不去重。
select device_id, gender, age, gpa from user_profile
where university = '山东大学'
union all
select device_id, gender, age, gpa from user_profile
where gender = 'male';
28、计算25岁以上和以下的用户数量
CASE函数 是一种多分支的函数,可以根据条件列表的值返回多个可能的结果表达式中的一个。 可用在任何允许使用表达式的地方,但不能单独作为一个语句执行。 分为: 简单CASE函数 搜索CASE函数
> 简单 CASE函数
CASE 测试表达式
WHEN 简单表达式1 THEN 结果表达式1
WHEN 简单表达式2 THEN 结果表达式2 …
WHEN 简单表达式n THEN 结果表达式n
[ ELSE 结果表达式n+1 ]
END
搜索CASE函数
CASE
WHEN 布尔表达式1 THEN 结果表达式1
WHEN 布尔表达式2 THEN 结果表达式2 …
WHEN 布尔表达式n THEN 结果表达式n
[ ELSE 结果表达式n+1 ]
END
题目:现在运营想要将用户划分为25岁以下和25岁及以上两个年龄段,分别查看这两个年龄段用户数量
select case when age <25 or age is null then '25岁以下'
when age >=25 then '25岁及以上'
end age_cut, count(*)number
from user_profile
group by age_cut
29、查看不同年龄段的用户明细
题目:现在运营想要将用户划分为20岁以下,20-24岁,25岁及以上三个年龄段,分别查看不同年龄段用户的明细情况,请取出相应数据。(注:若年龄为空请返回其他。)
select
device_id,
gender,
case
when age>=25 then '25岁及以上'
when age>=20 then '20-24岁'
when age<20 then '20岁以下'
else '其他'
end as age_cut
from user_profile
30、查看不同年龄段的用户明细
日期函数 DAYOFWEEK(date) 返回日期date的星期索引(1=星期天,2=星期一, ……7=星期六)。这些索引值对应于ODBC标准。
select DAYOFWEEK('1998-02-03')
-> 3
WEEKDAY(date) 返回date的星期索引(0=星期一,1=星期二, ……6= 星期天)。
mysql> select WEEKDAY('1997-10-04 22:23:00');
-> 5
DAYOFMONTH(date) 返回date的月份中日期,在1到31范围内。
mysql> select DAYOFMONTH(‘1998-02-03’); -> 3
DAYOFYEAR(date) 返回date在一年中的日数, 在1到366范围内。
mysql> select DAYOFYEAR('1998-02-03');
-> 34
MONTH(date) 返回date的月份,范围1到12。
mysql> select MONTH('1998-02-03');
-> 2
DAYNAME(date) 返回date的星期名字。
mysql> select DAYNAME("1998-02-05");
-> 'Thursday'
MONTHNAME(date) 返回date的月份名字。
mysql> select MONTHNAME("1998-02-05");
-> 'February'
QUARTER(date) 返回date一年中的季度,范围1到4。
mysql> select QUARTER('98-04-01');
-> 2
WEEK(date) 对于星期天是一周的第一天的地方,有一个单个参数,返回date的周数,范围在0到52。
mysql> select WEEK('1998-02-20');
-> 7
WEEK(date,first) 2个参数形式WEEK()允许你指定星期是否开始于星期天或星期一。 如果第二个参数是0,星期从星期天开始, 如果第二个参数是1,从星期一开始。
mysql> select WEEK('1998-02-20',0);
-> 7
mysql> select WEEK('1998-02-20',1);
-> 8
YEAR(date) 返回date的年份,范围在1000到9999。
mysql> select YEAR('98-02-03');
-> 1998
HOUR(time) 返回time的小时,范围是0到23。
mysql> select HOUR('10:05:03');
-> 10
MINUTE(time) 返回time的分钟,范围是0到59。
mysql> select MINUTE('98-02-03 10:05:03');
-> 5
SECOND(time) 回来time的秒数,范围是0到59。
mysql> select SECOND(‘10:05:03’); -> 3
PERIOD_ADD(P,N) 增加N个月到阶段P(以格式YYMM或YYYYMM)。以格式YYYYMM返回值。注意阶段参数P不是日期值。
mysql> select PERIOD_ADD(9801,2); -> 199803
PERIOD_DIFF(P1,P2) 返回在时期P1和P2之间月数,P1和P2应该以格式YYMM或YYYYMM。注意,时期参数P1和P2不是日期值。
mysql> select PERIOD_DIFF(9802,199703); -> 11
现在运营想要计算出2021年8月每天用户练习题目的数量,请取出相应数据。
select
day(date) as day, count(question_id) as question_cnt
from question_practice_detail
where month(date)= 8 and year(date) = 2021
group by date
31、计算用户的平均次日留存率
外连接:只限制一张表中的数据必须满足连接条件,而另一张表中数据可以不满足连接条件。
外连接的语法格式为: SELECT … FROM 表1 LEFT | RIGHT [OUTER] JOIN 表2 ON <连接条件> left join: 包含左表的所有行,对应的右表行可能为空 right join: 包含右表的所有行,对应的左表行可能为空 full join: 只包含左右表都匹配并且不为空的行
现在运营想要查看用户在某天刷题后第二天还会再来刷题的平均概率。请你取出相应数据。
SELECT count(distinct q2.device_id,q2.date)/count(distinct q1.device_id,q1.date) as avg_ret
FROM question_practice_detail as q1 left outer join question_practice_detail as q2
on q1.device_id=q2.device_id and datediff(q2.date,q1.date)=1;
32、 统计每种性别的人数
可使用substring_index函数可以按特定字符串截取源字符串。 substring_index(FIELD, sep, n)可以将字段FIELD按照sep分隔: (1).当n大于0时取第n个分隔符(n从1开始)左边的全部内容; (2).当n小于0时取倒数第n个分隔符(n从-1开始)右边的全部内容;
select
substring_index(profile, ',', -1) as gender,
count(device_id) as number
from user_submit
group by gender;
33、 统计每种性别的人数
题目:现在运营举办了一场比赛,收到了一些参赛申请,表数据记录形式如下所示,现在运营想要统计每个年龄的用户分别有多少参赛者,请取出相应结果
select
substring_index(substring_index(profile, ',', 3),',', -1) as age,
count(device_id) as number
from user_submit
group by age
34、 提取博客URL中的用户名
select – 替换法 replace(string, ‘被替换部分’,‘替换后的结果’) – device_id, replace(blog_url,‘http:/url/’,‘’) as user_name
– 截取法 substr(string, start_point, length可选参数) – device_id, substr(blog_url,11,length(blog_url)-10) as user_nam
– 删除法 trim(‘被删除字段’ from 列名) – device_id, trim(‘http:/url/’ from blog_url) as user_name
– 字段切割法 substring_index(string, ‘切割标志’, 位置数(负号:从后面开始)) device_id, substring_index(blog_url,‘/’,-1) as user_name
from user_submit;
对于申请参与比赛的用户,blog_url字段中url字符后的字符串为用户个人博客的用户名,现在运营想要把用户的个人博客用户字段提取出单独记录为一个新的字段,请取出所需数据。
select device_id,
substring_index(blog_url,"/", -1) as user_name
from user_submit
35、 找出每个学校GPA最低的同学
窗口函数语法
<窗口函数> over (partition by <用于分组的列名>
order by <用于排序的列名>)
<窗口函数>的位置,可以放以下两种函数:
专用窗口函数,比如rank, dense_rank, row_number等 rank 如果有并列名次的行,会占用下一名次的位置 1 1 3 dense_rank 如果有并列名次的行,不占用下一名次的位置 1 1 2 row_number 如果有并列名次的行,也不考虑并列名次的情况 1 2 3 聚合函数,如sum. avg, count, max, min等 针对自身记录、以及自身记录之上的所有数据进行计算
现在运营想要找到每个学校gpa最低的同学来做调研,请你取出每个学校的最低gpa
SELECT device_id, university,gpa FROM
(SELECT device_id, university,gpa,
RANK() over (PARTITION BY university ORDER BY gpa) rk FROM user_profile) up
WHERE up.rk=1;
如果对大家有所帮助,希望能够给个赞,感谢各位!
|