十个精妙绝伦的SQL语句,说尽SQL精华

news2024/11/23 21:46:40

目录

    • 引子
    • 十大SQL
      • 1. 统计班级总分前十名
      • 2. 删除重复记录, 且保留一条
      • 3. 最大连续登陆天数的问题
      • 4. 计算除去部门最高工资,和最低工资的平均工资
      • 5. 计算占比和同比增长
      • 6. 算成绩
      • 7.算昨天每个城市top 10消费金额的用户,输出city_id,city_name,uid, 消费总金额
      • 8. 求连续点击三次的用户数,中间不能有别人的点击 ,最大连续天数的变形问题
      • 9. AB球队得分流水表,得到连续三次得分的队员名字 和每次赶超对手的球员名字
      • 10. 举例说明内连接、外连接、左连接、右连接的区别
    • SQL语法图解
    • 窗口函数
    • 参考

引子

哪些是程序员的通用能力?算法、正则表达式和SQL。这三样,是程序员的基本功,就跟数学公式一样,它不涉及智商,但关乎你的学习态度,牵扯到程序员的面子。面试官考这些时,如果连这个都不会,就会遭到鄙视。有次有个应聘者质疑我,说术业有专攻,你不该考这些问题,说我这是在问茴字的四种写法。

十大SQL

1. 统计班级总分前十名

表结构stu_score:(student_id, course_id, score)

select student_id, sum(score) as s from stu_score group by student_id order by s desc limit 10

这道题比较基本,考察聚合函数用法。下面两个进阶一点:
要求输出课程号和选修人数,查询结果按人数降序排序,若人数相同,按课程号升序排序

select 课程号,count(学号) as 选修人数
from score
group by 课程号
having 选修人数 >=2
order by 选修人数 desc, 课程号 asc;

查询没有学全所有课的学生的学号、姓名

select 学号,姓名
from student
where 学号 in
(select 学号
from score
group by 学号
having count(课程号) < (select count(课程号) from course));

2. 删除重复记录, 且保留一条

表结构: (book_id, book_name)
从书籍列表里,删除书名重复的记录,保留book_id最小的记录:

delete from ebook
where book_name in (select book_name from ebook group by book_name having count(*) > 1)
  and book_id not in (select min(book_id) from ebook group by book_name having count(*)>1);

这个考察了子查询和min()函数以及having子句的使用。很多数据库都支持这种子查询。注意,上述SQL在MySQL中执行会报错:

[HY000][1093] You can't specify target table 'ebook' for update in FROM clause

这是因为MySQL不允许你在做子查询时去修改表。trick的办法是创建临时表:

delete from ebook
where book_name in (select t1.book_name from (select book_name 
         from ebook group by book_name having count(*) > 1) as t1)
     and book_id not in (select t2.id from (select min(book_id) as id 
         from ebook group by book_name having count(*)>1) as t2);

上面创建了两张临时表t1和t2。这样MySQL就可以执行了。

3. 最大连续登陆天数的问题

题目: 找出连续7天登陆,连续30天登陆的用户。
考察点:窗口函数

select *
fromselect user_id ,count(1) as num
  from
     (select user_id,date_sub(log_in_date, rank) dts
          from  (select user_id,log_in_date,	
                  row_number() over(partitioned by user_id order by log_in_date ) as rank
		  from user_log
	          )t
      )a
  group by dts
)b
where num = 7  

4. 计算除去部门最高工资,和最低工资的平均工资

emp 表:(id 员工 id ,deptno 部门编号,salary 工资)

核心是使用窗口函数降序和升序分别排一遍就取出了最高和最低。

select a.deptno,avg(a.salary)
from  
 (
 select *, rank() over( partition by deptno order by salary ) as rank_1
 , rank() over( partition by deptno order by salary desc) as rank_2 
 from emp
 )  a 
group by a.deptno
where a.rank_1 >1 and a.rank_2 >1 

5. 计算占比和同比增长

t_user记录了用户注册时间和平台,统计2018年1月份
每天各平台(“ios”,“android”,“h5”)注册用户总量占所有平台总用户的比例,以及各平台注册用户按周同比增长(与一周前相比)的比例

建表语句

create table t_user
(
uid BIGINT COMMENT "用户id"
, reg_time STRING COMMENT "注册时间,如2018-07-01 08:11:39"
, platform STRING COMMENT "注册平台,包括app ios h5"
);

解答:
知识点:窗口函数。
注意:如果存在某天的缺失数据,偏移函数会有错误

SELECT a.reg_date
,a.platform
,ROUND(a.reg_num/sum(a.reg_num)over(PARTITION BY a.reg_date),4) as rate
,ROUND((a.reg_num-a.reg_num_7)/a.reg_num_7,4) as rate_week
FROM(
SELECT 
DATE(reg_time) as reg_date
,platform
,COUNT(uid) as reg_num
,lag(COUNT(uid),7)over(PARTITION BY platform ORDER BY DATE(reg_time)) as reg_num_7
FROM t_user
WHERE SUBSTR(reg_time,1,7)='2018-01'
GROUP BY DATE(reg_time),platform
) a ;

6. 算成绩

表名:subject_scores
输入
Name subject score
王建国 数学 95
王建国 语文 89
李雪琴 数学 100
李雪琴 语文 100
李雪琴 英语 100

输出
Name math chinese English
王建国 95 89 0
李雪琴 100 100 100

解答:
所涉知识点:GROUP BY 和 CASE WHEN 实现行变列
注意:(1)空的数据这里判断为0;(2)CASE WHEN 前要使用聚合函数,不然报错)

SELECT 
name,
MAX(CASE subject WHEN '数学' THEN score ELSE 0 END) as math,
MAX(CASE subject WHEN '语文' THEN score ELSE 0 END) as chinese,
MAX(CASE subject WHEN '英语' THEN score ELSE 0 END) as English
FROM subject_scores 
GROUP BY name;

7.算昨天每个城市top 10消费金额的用户,输出city_id,city_name,uid, 消费总金额

表名:orders
每次消费记录一条
city_id,city_name,uid,order_id,amount,pay_order_time, pay_date
解答:(窗口函数)

SELECT a.city_id,
a.city_name,
a.uid,
a.pay_amount as '消费总金额'
FROM 
(
SELECT city_id,city_name,uid,SUM(amount) as pay_amount,RANK()over(PARTITION BY city_id ORDER BY SUM(amount) DESC) as rank_no
FROM orders
WHERE pay_date='2020-01-01'
GROUP BY city_id,city_name,uid 
) a 
WHERE a.rank_no<=10;

8. 求连续点击三次的用户数,中间不能有别人的点击 ,最大连续天数的变形问题

总结:相邻问题的本质就是基于研究对象(比如用户、会员、员工等),利用窗口函数对时间字段进行有差别的排序,然后基于研究对象和新增的{排序差值列},进行分组计数的求连续点击、签到、复购等业务问题的计算;

'''
a表记录了点击的流水信息,包括用户id ,和点击时间
usr_id a a b a a a a
click_time t1 t2 t3 t4 t5 t6 t7

'''
--  方式一:      
use demo;       
WITH t1 AS (
		SELECT MemberID AS user_id, STime AS click_time
		FROM OrderList
		WHERE MemberID IS NOT NULL
		/*选取demo.OrderList 作为底表测试数据*/
			AND DATE_FORMAT(STime, '%Y-%m') = '2017-02'
	), 
	t2 AS (
		SELECT  *
				, row_number() OVER (ORDER BY click_time) AS rank1
				, row_number() OVER (PARTITION BY user_id ORDER BY click_time) AS rank2
		FROM t1
	), 
	t3 AS (
		SELECT *, rank1 - rank2 AS diff
		FROM t2
	), 
	t4 AS (
		SELECT DISTINCT user_id
		FROM t3
		GROUP BY user_id, diff
		HAVING COUNT(1) > 3
	)
-- SELECT  * from t4 ;
SELECT *
FROM t3
WHERE user_id IN (
	SELECT user_id
	FROM t4
)
ORDER BY user_id, diff, click_time;       
        
--  方式二:        
        
SELECT DISTINCT user_id
FROM (
	SELECT *, rank_1 - rank_2 AS diff
	FROM (
		SELECT  *
		       ,row_number() OVER (ORDER BY click_time) AS rank_1
		       ,row_number() OVER (PARTITION BY user_id ORDER BY click_time) AS rank_2
		FROM (
			SELECT MemberID AS user_id, STime AS click_time
			FROM OrderList
			WHERE MemberID IS NOT NULL 
				  /*选取demo.OrderList 作为底表测试数据*/
				  AND DATE_FORMAT(STime, '%Y-%m') = '2017-02'
		) a
	) b
) c
GROUP BY diff, user_id
HAVING COUNT(1) > 3; 

9. AB球队得分流水表,得到连续三次得分的队员名字 和每次赶超对手的球员名字

表结构:

create table bktab (
   team  string comment '球队名称',
   number int comment '球员号码',
   score_time string comment '得分时间',
   score int comment '得分分数',
   name string comment '球员姓名')
comment 'AB球队得分流水表'
row format delimited fields terminated by '\t'
lines terminated by '\n' stored as orc;

分析思路:
1.按score_time 对全局排序
2.获取当前行 A队累计得分 B队累计得分
3.获取 当前 A队累计得分 与 B队累计得分的差值
4.当前行差值 与上一行差值,发生符合变化时,表示 分数发生了反超



-- 查询sql
select
    team
    ,number
    ,score_time
    ,score
    ,name
    ,ateam_score
    ,bteam_score
from (

    select
        team
        ,number
        ,score_time
        ,score
        ,name
        ,ateam_score
        ,bteam_score
        ,diff_score
        ,lag(diff_score) over (order by score_time asc) as pre_diff_score
        ,case when diff_score > 0 and lag(diff_score) over (order by score_time asc) < 0 then 1
              when diff_score < 0 and lag(diff_score) over (order by score_time asc) > 0 then 1
              when diff_score is not null and lag(diff_score) over (order by score_time asc) is null then 1
              else 0
         end as if_surpass

    from (
        select
        team
        ,number
        ,score_time
        ,score
        ,name
        ,sum(if(team = 'A',score,0)) over (order by score_time asc) as ateam_score
        ,sum(if(team = 'B',score,0)) over (order by score_time asc) as bteam_score
        ,sum(if(team = 'A',score,0)) over (order by score_time asc) - sum(if(team = 'B',score,0)) over (order by score_time asc) as diff_score
        from bktab
    ) t1
) t2
where if_surpass = 1
;

10. 举例说明内连接、外连接、左连接、右连接的区别

下图展示了 LEFT JOIN、RIGHT JOIN、INNER JOIN、OUTER JOIN 相关的 7 种用法:
在这里插入图片描述
查询所有课程成绩小于60分学生的学号、姓名

SELECT A.学号,B.姓名 FROM score A LEFT JOIN student B ON A.学号 = B.学号 GROUP BY A.学号 HAVING MAX(成绩) < 60;
SELECT customer.last_name, city.name
FROM customer
INNER JOIN city
  ON customer.id = city.customer_id;
SELECT c.last_name AS lname, t.name AS city
FROM customer AS c
INNER JOIN city AS t
  ON c.id = t.customer_id;
SELECT last_name FROM customer
INTERSECT
SELECT last_name FROM employee;

You can join tables using JOIN, including INNER JOIN, LEFT JOIN, RIGHT JOIN, FULL JOIN, and CROSS JOIN (please see the courses listed at the end of this article for more information). In this example, we want to join data from the tables customer and city. INNER JOIN needs to come after FROM and the name of the first table, customer. After INNER JOIN, place the name of the second table, city. The records with data from both tables are matched by ON with the condition to join. The records in the table city are matched to the records from the table customer if they have the same value in the column id in the table customer and in the column customer_id in the table city.

SQL语法图解

在这里插入图片描述

在这里插入图片描述

窗口函数

窗口函数的基本语法如下:

<窗口函数> over (partition by <用于分组的列名>
                order by <用于排序的列名>)

窗口函数包括:
1) 专用窗口函数,如rank, dense_rank, row_number等专用窗口函数
2) 聚合函数,如sum. avg, count, max, min等

因为窗口函数是对where或者group by子句处理后的结果进行操作,所以窗口函数原则上只能写在select子句中。

参考

  • https://zhuanlan.zhihu.com/p/92654574

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/91486.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

C语言刷题(3)

&#x1f412;博客名&#xff1a;平凡的小苏 &#x1f4da;学习格言&#xff1a;别人可以拷贝我的模式&#xff0c;但不能拷贝我不断往前的激情 目录 计算体重指数 计算三角形周长和面积 KiKi和酸奶 网购 变种水仙花 计算体重指数 描述 问题&#xff1a;计算BMI指数&#xff0…

安全可信 | 强墙出击!天翼云Web应用防火墙(原生版)硬核亮相!

12月9日&#xff0c;由中国信息通信研究院主办的“墙墙联合——云上防火墙技术沙龙”在线上顺利举行&#xff0c;天翼云科技有限公司研发专家吴雷分享了新标准、新需求下云Web应用防火墙&#xff08;云WAF&#xff09;的发展方向&#xff0c;并介绍了天翼云Web应用防火墙&#…

如何从 OVF 或 OVA 文件中部署虚拟机

从 OVF 或 OVA 文件中部署虚拟机 使用新建虚拟机向导从 OV F和 VMDK 文件或 OVA 文件部署虚拟机。由于 Web 浏览器的限制,OVA 部署仅限于1GB以下的文件。要部署大于1GB的 OVA 文件,请使用 tar 提取 OVA 文件并分别提供OVF和VMDK文件。 一、右键单击导航器中的‘‘虚拟机“,…

Android:远程调试WebView

目录 前言 配置WebView 手机设置 远程调试 前言 APP中使用WebView展示网页的结果可能不太理想&#xff0c;那么我们想调试的话就没有在浏览器当中调试方便&#xff0c;不过谷歌浏览器给我们提供了能远程调试的方案。 官方文档&#xff1a;https://developer.chrome.com…

Blazor也可以用MarkDown!Vditor-Blazor基础使用教程以及部分源码解析!Ant-Designer-Blazor

前言 Ant-Designer-Blazor组件库是一款非常好用的Blazor的UI框架库&#xff0c;使用很少的精力就可以搭建出一个漂亮的UI界面了。 但是Ant-Designer-Blazor中尚缺少对MarkDown组件的支持&#xff0c;所以只能下载Nuget包里面的一个Vditor&#xff08;也是Ant-Designer的&#…

设计师常用网站,建议收藏

这几个设计师常用网站&#xff0c;你不知道就落后了 设计党赶紧收藏&#xff01;1、菜鸟图库 https://www.sucai999.com/?vNTYwNDUx 免费设计素材。 站内平面海报、UI设计、电商淘宝、免抠、高清图片、样机模板等素材非常齐全。还有在线抠图、CDR版本转换功能&#xff0c;能有…

坦克大战③

1.防止敌人坦克重叠运动 八种情况 这辆敌方坦克和任何其它敌方坦克都不发生碰撞时且不超边界时才可以移动 2.记录玩家成绩 绘制版面信息 paint()方法中如果没有super.paint(g)&#xff0c;那么绘制的敌方坦克数会出现重叠情况 调用方法 在Recorder类中定义一个方法…

Java 性能诊断工具简介-EJ Technologies JProfiler 12.0.5 中文激活版

目录 JProfiler 这篇文章讲解的比较详细&#xff1a; 可以辅助命令&#xff0c;应用jar的启动命令&#xff1a; 同时在开发工具里面添加一个JProfiler插件 JProfiler 这篇文章讲解的比较详细&#xff1a; JVM性能分析工具 Jprofiler - 百里浅暮 - 博客园 我在这里记录下。…

MATLB|电动汽车充放电的最优调度

目录 一、概述 二、电动汽车 2.1 电动汽车的类型 2.2电动汽车行程开始时间 2.3 电动汽车行驶里程 三、Matlab实现 3.1 代码前的准备 3.2 运行结果 四、往期回顾 五、Matlab代码实现 一、概述 电动汽车能够良好发展离不开精确的电动汽车充电负荷预测,目前,大多数充电负…

2022全年度烘干机十大热门品牌销量榜单

在“宅经济”时代&#xff0c;人们对大家电的需求持续高速增长。在当前的大环境下&#xff0c;人们的健康意识在不断提高&#xff0c;拥有除菌防菌功能的烘干机也更受欢迎。因此&#xff0c;烘干机作为快速进入普及阶段的家电新品&#xff0c;市场增长空间非常大。 根据鲸参谋数…

RCE绕过靶场练习

目录 CTF-01 CTF-02 CTF-03 CTF-04 CTF-05 CTF-01 测试回显 Array ([0] > PING 127.0.0.1 (127.0.0.1): 56 data bytes[1] > 64 bytes from 127.0.0.1: seq0 ttl42 time0.028 ms[2] > 64 bytes from 127.0.0.1: seq1 ttl42 time0.059 ms[3] > 64 bytes from …

Javascript 面向对象的缺陷,父类能调用被子类重写后的方法

问题背景 前些天做项目练手时&#xff0c;遇到一个需要写类的场景&#xff0c;各个类之间的交互我打算用事件的方式进行&#xff0c;就自然地在父类继承了EventEmitter类。然后在父类对一个具体事件注册了一个默认监听&#xff0c;子类通过注册自己专有的监听细化逻辑。代码逻…

win7、win10关闭驱动签名,进入驱动测试模式,以及常见初级问题的解决

win7关闭驱动签名&#xff0c;进入驱动测试模式win7、win10关闭驱动签名、进入驱动测试模式DebugView工具运行提示"Dbgv.sys: 拒绝访问"驱动项目配置属性常用设置驱动中KdPrint打印UNICODE_STRING字符串常用方法没使用的变量在编译时报警告&#xff1a;未引用的形参错…

文字转语音真人发声软件哪个好?这些实用软件快来收好

平时大家结束了一天的工作&#xff0c;会不会在空闲时间好好放松一下呢&#xff1f;如果是坐公交车或者地铁的小伙伴&#xff0c;想要在下班途中看一些电子书籍或者新闻&#xff0c;却因为下班高峰期人潮拥挤&#xff0c;导致无法腾出手来阅读&#xff0c;这时候你们会怎么解决…

红队基础知识

文章目录红队前置准备网络攻击链工程和操作攻击性思维渗透测试漏洞研究软件开发基础设施网络和系统逆向工程社会工程学物理安全威胁情报安全事件的检测和响应技术写作培训与汇报总结红队前置准备 红队通常指在对抗情况下需要仿真、模拟或以其他方式扮演某个、某组入侵者或理论…

【Docker】(一)基本概念与安装使用

1.概述 最近学习了Docker的使用&#xff0c;想通过一个系列的笔记来记录学习的过程与收获&#xff0c;并为以后的生产工作提供指导。 我一直认为学习一门技术时&#xff0c;需要先了解这门技术的基本概念&#xff0c;了解它能解决的问题&#xff0c;这样才能定位明确的学习目标…

frp内网穿透https

在公网服务器搭建frps(service)&#xff0c;在内网本地机子搭建frpc(client)&#xff0c;流量通过访问公网ip&#xff0c;经过frps服务端转发到fprc客户端&#xff0c;fprc再转发到本地web应用。 官方下载地址​ https://github.com/fatedier/frp/releases 官方文档地址https…

智能门锁“激战正酣”

近年来&#xff0c;智能化已经成为了高频词&#xff0c;越来越多的行业都在朝着智能化方向发展&#xff0c;家居行业也不例外。受技术升级、居民收入水平提高等多重因素影响&#xff0c;整个智能家居行业呈现出了蓬勃发展态势。据亿欧智库预测&#xff0c;2025年中国智能家居市…

客运车票网站

开发工具(eclipse/idea/vscode等)&#xff1a; 数据库(sqlite/mysql/sqlserver等)&#xff1a; 功能模块(请用文字描述&#xff0c;至少200字)&#xff1a; 题目&#xff1a;基于Wb的公路客运车票信息管理系统设计与实现 时了解客运站动态。 角色&#xff1a;乘客、管理员 (2)车…

[附源码]Node.js计算机毕业设计-高校人事管理系统Express

项目运行 环境配置&#xff1a; Node.js最新版 Vscode Mysql5.7 HBuilderXNavicat11Vue。 项目技术&#xff1a; Express框架 Node.js Vue 等等组成&#xff0c;B/S模式 Vscode管理前后端分离等等。 环境需要 1.运行环境&#xff1a;最好是Nodejs最新版&#xff0c;我…