力扣刷题(sql)--零散知识点(1)

通过一段时间的刷题,感觉自己的sql能力逐渐上去,所以不会像前三道题一样讲那么详细了,这里主要会讲到一些特殊的知识点和方法。另外,我的建议是做完一个题有好的想法赶紧记录下来,不要想着最后汇总,不然会懒得整理,也会忘记一些当时才发现的知识点。

------------------------------------------------------------------------------------------------------------------------

1. 不用if的sum

这里的sum(order_date= customer_pref_delivery_date),没有用到if也能用聚集函数sum把满足order_date= customer_pref_delivery_date条件的行数加起来。说明有的时候可以不用if,用if的话还要设置两个正确与否的值,通常是1和0.

selectround(sum(order_date= customer_pref_delivery_date)/count(*)*100,2) immediate_percentage
fromdelivery
where(customer_id,order_date)
in(selectcustomer_id, min(order_date)  fromdeliverygroup bycustomer_id);

2. 多个列名的in

上面代码的where后面是判断某一行中两列对应的值能否另一个表(这里是个子查询)对上。我们之前往往用到的都是只有一个列,比如where id in (201,203),这里可以很好的扩展思维,个人认为很有用的知识点。

3. datediff的误区

selectactivity_date day , count(distinct user_id) active_users
fromactivity
wheredatediff('2019-07-27',activity_date)<29
group byactivity_date;

这里我想找出activity_date在’2019-07-27’近 30 天的日期,但是后面我发现这是错的,因为没有限制 activity_date 不能超出‘2019-07-27’。这会导致某些未来的日期(如 2019-08-252021-08-25)也符合条件(做差后为负数,也小于29)。

所以解决这一问题的方法就是用between。between也有两种用法:

activity_date BETWEEN DATE_SUB('2019-07-27', INTERVAL 29 DAY) AND '2019-07-27'DATEDIFF('2019-07-27', activity_date) BETWEEN 1 AND 29

以上两种都可以实现找到近 30 天日期的作用。

******值得一提的是,题目要求近30天,而上面的代码输入的关键字都是29,这点需要注意,因为DATEDIFF() 的结果是天数差,不包括起始日期的那一天。

4. min()求最小日期

MIN()函数:会返回某个列中的最小值,在时间数据上,它返回最早的日期。

select MIN(activity_date) from activity;

5. lag()窗口函数

刷题的时候用到了一下,感觉特别好用,再次讲解一下,这次还用到了“PARTITION BY

LAG() 是 SQL 中的一种窗口函数,用于获取当前行的前一行的值,而无需在查询中自连接。这在需要对比相邻记录(如日期、订单、活动等)时非常有用。 

语法如下:

LAG(column_name, [offset], [default_value]) 
OVER (PARTITION BY partition_column ORDER BY order_column)

实际用例:

user_idactivity_dateactivity_type
12019-07-20open_session
12019-07-21send_message
12019-07-22end_session
22019-07-21open_session
22019-07-23end_session
SELECT user_id, activity_date, activity_type,LAG(activity_date) OVER (PARTITION BY user_id ORDER BY activity_date) AS previous_activity_date
FROM activity;

结果:

user_idactivity_dateactivity_typeprevious_activity_date
12019-07-20open_sessionNULL
12019-07-21send_message2019-07-20
12019-07-22end_session2019-07-21
22019-07-21open_sessionNULL
22019-07-23end_session2019-07-21

有的时候还是能发挥一定的作用。 

6.筛选部分组内数据满足条件的分组

例题:编写解决方案,报告 2019年春季 才售出的产品。即 仅 在 2019-01-01 (含)至 2019-03-31 (含)之间出售的商品。

输入:
Product table:
+------------+--------------+------------+
| product_id | product_name | unit_price |
+------------+--------------+------------+
| 1          | S8           | 1000       |
| 2          | G4           | 800        |
| 3          | iPhone       | 1400       |
+------------+--------------+------------+
table:
+-----------+------------+----------+------------+----------+-------+
| seller_id | product_id | buyer_id | sale_date  | quantity | price |
+-----------+------------+----------+------------+----------+-------+
| 1         | 1          | 1        | 2019-01-21 | 2        | 2000  |
| 1         | 2          | 2        | 2019-02-17 | 1        | 800   |
| 2         | 2          | 3        | 2019-06-02 | 1        | 800   |
| 3         | 3          | 4        | 2019-05-13 | 2        | 2800  |
+-----------+------------+----------+------------+----------+-------+
输出:
+-------------+--------------+
| product_id  | product_name |
+-------------+--------------+
| 1           | S8           |
+-------------+--------------+

 刚开始我写的代码如下:

selectp.product_id, p.product_name
fromproduct p
joinsales s
onp.product_id = s.product_id
anddate(s.sale_date) between '2019-01-01' and '2019-03-31'; 

上面代码利用简单联结找出sale_date在2019-01-01到2019-03-31,这样会返回错误的结果,因为产品2不仅在这个区间里出售了,在其他区间也出售了,没有实现“仅”的目的。

后面使用分组(group by+having)的办法,比较巧妙的解决了这一问题,即对该组内所有数据都进行验证,排除这种有的满足、有的不满足的数据,却加入了要求所有数据满足的分组里面。

# Write your MySQL query statement below
selectp.product_id, p.product_name
fromproduct p
joinsales s
onp.product_id = s.product_id
group byp.product_id, p.product_name
havingmin(sale_date) >= '2019-01-01' and max(sale_date) <= '2019-03-31';

即GROUP BY + HAVING:适用于简单的按组汇总,并进行唯一性判断。

7. distinct在多列上的的使用

DISTINCT 是 SQL 中的关键字,用于去除查询结果中的重复行,返回唯一值。它通常用于 SELECT 语句中,确保查询的结果集中不包含重复的数据。

这里DISTINCT 不仅可以应用于单列,也可以用于多个列(放在多个列名的最前面),它会返回这些列的组合的唯一值。

SELECT DISTINCT product_id FROM sales;SELECT DISTINCT product_id, buyer_id FROM sales;

---------------------------------------------------------------------------------------------------------------------------------例题: 一个员工可以属于多个部门。当一个员工加入超过一个部门的时候,他需要决定哪个部门是他的直属部门。请注意,当员工只加入一个部门的时候,那这个部门将默认为他的直属部门,虽然表记录的值为'N'.

输入:
Employee table:
+-------------+---------------+--------------+
| employee_id | department_id | primary_flag |
+-------------+---------------+--------------+
| 1           | 1             | N            |
| 2           | 1             | Y            |
| 2           | 2             | N            |
| 3           | 3             | N            |
| 4           | 2             | N            |
| 4           | 3             | Y            |
| 4           | 4             | N            |
+-------------+---------------+--------------+
输出:
+-------------+---------------+
| employee_id | department_id |
+-------------+---------------+
| 1           | 1             |
| 2           | 1             |
| 3           | 3             |
| 4           | 3             |
+-------------+---------------+

这题我写了很长串,思路是先把有“Y”的分一组,然后其他没“Y”就是只有一行的分一组,然后拼起来。我觉得太长,而gpt给出了两种方法,可以来学习一下。(gpt懂得太多了,有能借鉴而且实用的才拿出来记录下。)

8. max()配合case求出分组中某个符合条件的值

如图所示,下面是上一题的更优解,这里用到了一些配合。

SELECT employee_id, COALESCE(MAX(CASE WHEN primary_flag = 'Y' THEN department_id ELSE NULL END),MAX(department_id)) AS department_id
FROM employee
GROUP BY employee_id;

首先来个错误示范(我写的):

SELECT employee_id, if(primary_flag='Y',department_id,null) department_id
FROM employee
GROUP BY employee_id;

代码意思好像要求把分组后primary_flag='Y'的department_id值打印出来,结果如图:

employee_id为1和3返回null正常,它们没有符合primary_flag='Y'条件的行,但employee_id为4有满足条件的行,但也返回null,说明语法还是有问题,貌似这里只会判断每一组的第一行是否满足rimary_flag='Y'条件,所有2有返回值,4返回null

这里就要配合max()函数了,MAX(CASE WHEN primary_flag = 'Y' THEN department_id ELSE NULL END),这里if和case差别不大,作用都一样,条件语句把每一组的每一行判断条件后每一行都会得到要么是一个数值,要么是null,用max()比较数值和null后,就能让那个合适的返回值返回出来了。

这里加上max()函数后,2和4就能正常返回正确的department_id值了,但1和3依旧返回null,因为它们压根没有primary_flag='Y'条件的行啊。为了满足题意,即只有一行时,不管primary_flag='Y'条件是否成立,都返回其department_id,那还要配合COALESCE()。 

9.COALESCE()

COALESCE() 是 SQL 中的一个非常实用的空值处理函数,用于返回第一个非 NULL 的值。它的主要作用是提供一个默认值,避免返回 NULL 结果。这个函数在处理缺失数据、替代空值、进行多层判断时非常有用。coalesce(合并的意思)

COALESCE(value1, value2, ..., valueN)

下面的代码当employee_id的1、3的max()配合case依然返回null后,直接返回其department_id,这个不是null,直接返回。

 COALESCE(MAX(CASE WHEN primary_flag = 'Y' THEN department_id ELSE NULL END),department_id)

8、9的总结:希望能很好地帮助到以后对某个列分组后求另外一个列符合条件的值。 

10. ROW_NUMBER()

依然是刚才那题,看一下另一种思路:

WITH ranked_departments AS (SELECT employee_id, department_id, ROW_NUMBER() OVER (PARTITION BY employee_id ORDER BY primary_flag DESC) AS rnFROM employee
)
SELECT employee_id, department_id
FROM ranked_departments
WHERE rn = 1;

这些代码的思路大概是:用到了一个类似子表的东西,同时自己设置了一列,这一列是利用ROW_NUMBER(),根据employee_id分区,然后通过primary_flag这一列来排序最终设计得到,最后在新表中根据新得到的这一列,取出新列中所有编号为1的employee_id, department_id.

这里的语法和之前的lag()函数一样。

ROW_NUMBER() 是 SQL 中的一个窗口函数,用于为查询结果中的每一行分配一个唯一的编号,这个编号通常按某种顺序排列(如时间、ID等)。它常用于需要按某种顺序进行排序、排名或者找出每个分组的第一条或最后一条记录的场景。

ROW_NUMBER() OVER (PARTITION BY partition_column ORDER BY order_column)

这种编号后提取指定编号的思维值得学习。 

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

通过cv库智能切片 把不同的分镜切出来 自媒体抖音快手混剪

用 手机自动化脚本&#xff0c;从自媒体上获取视频&#xff0c;一个商品对应几百个视频&#xff0c;我们把这几百个视频下载下来&#xff0c;进行分镜 视频切片&#xff0c;从自媒体上下载视频&#xff0c;通过cv库用直方图识别每个镜头进行切片。 下载多个图片进行视频的伪原…

香橙派5(RK3588)使用npu加速yolov5推理的部署过程

香橙派5使用npu加速yolov5推理的部署过程 硬件环境 部署过程 模型训练(x86主机) 在带nvidia显卡(最好)的主机上进行yolo的配置与训练, 获取最终的best.pt模型文件, 详见另一篇文档 模型转换(x86主机) 下载airockchip提供的yolov5(从pt到onnx) 一定要下这个版本的yolov5, …

sass软件登录设定——未来之窗行业应用跨平台架构

一、saas软件开发中登录设计 以为大公司为参考思迅在登录时候需要录入商户号 二、独立商户商户好处 1.每个店铺的账户是独立的&#xff0c;保护商户职员账户信息的相对安全。 2.不同店铺可以试用相同用户名

LDR6020:为VR串流线方案注入高效能与稳定性

随着虚拟现实&#xff08;VR&#xff09;技术的不断发展&#xff0c;VR设备已经成为连接用户与沉浸式体验的重要桥梁。而VR串流线&#xff0c;作为这一技术的重要组成部分&#xff0c;更是承担着传输高质量图像、音频及数据的重任。在这个过程中&#xff0c;一款功能强大、性能…

【计网】从零开始认识IP协议 --- 认识网络层,认识IP报头结构

从零开始认识IP协议 1 网络层协议1.1 初步认识IP协议1.2 初步理解IP地址 2 IP协议报头3 初步理解网段划分 1 网络层协议 1.1 初步认识IP协议 我们已经熟悉了传输层中的UDP和TCP协议&#xff0c;接下来我们来接触网络层的协议&#xff1a; 网络层在计算机网络中的意义主要体现…

寻找大自然的颜色

走在停停&#xff0c;停停走走&#xff0c;恍惚间一天过去了&#xff0c;转瞬间一年过去了&#xff0c;身边的一切在变化又不在变化&#xff0c;生活是自己的又不是自己的。 今天是个特殊的日子&#xff0c;其实前几天对我而言就算特殊的日子了&#xff0c;一个心里暗暗等待着却…

Maven项目管理工具-初始+环境配置

1. Maven的概念 1.1. 什么是Maven Maven是跨平台的项目管理工具。主要服务于基于Java平台的项目构建&#xff0c;依赖管理和项目信息管理。 理想的项目构建&#xff1a;高度自动化&#xff0c;跨平台&#xff0c;可重用的组件&#xff0c;标准化的流程 maven能够自动下载依…

python项目实战——多线程爬虫

多线程爬虫 文章目录 多线程爬虫概念并行并发Python多线程用途threading模块小知识----函数体内pass的用处1. **占位符**2. **控制结构**3. **定义接口**总结 代码解读单线程--串行多线程--并行查看当前程序的线程让主函数等待子线程结束&#xff0c;再运行---.join()join()方法…

C# 串口通信教程

串口通信&#xff08;Serial Communication&#xff09;是一种用于设备之间数据传输的常见方法&#xff0c;通常用于与外部硬件设备&#xff08;如传感器、机器人、微控制器&#xff09;进行通信。在 C# 中&#xff0c;System.IO.Ports 命名空间提供了与串口设备交互的功能&…

【Linux | 网络I/O模型】五种网络I/O模型详解

1、数据传输过程 在 Linux 系统中&#xff0c;数据传输是通过 I/O 操作来实现的。I/O 操作是指数据从应用程序到内核&#xff0c;再到硬件设备&#xff08;如磁盘、网络接口&#xff09;的过程。 操作系统为了保护自己&#xff0c;设计了用户态、内核态两个状态。应用程序一般工…

数据库的诗篇:深入探索 MySQL 表操作的艺术与哲学

文章目录 前言&#x1f338;一、创建表——搭建数据存储的基础框架1.1 基本语法1.2 创建表的实际案例解释&#xff1a; 1.3 表设计的最佳实践 &#x1f338;二、查看表结构——快速了解数据库设计2.1 使用 DESC 命令解释&#xff1a; 2.2 使用 SHOW COLUMNS 命令2.3 使用 SHOW …

Java线程安全

目录 一.引入 二.介绍 1.概念 2.产生的原因 三.修改操作不是原子性 1.分析问题 2.解决问题&#xff08;锁&#xff09; 四.可重入与不可重入 五.死锁 1.引入 2.死锁的三种情况 3.构成死锁的必要条件 六.内存可见性 1.引入 2.产生原因 3.解决问题 七.指令重排序…

让你的 IDEA 使用更流畅 | IDEA内存修改

随着idea使用越来越频繁&#xff0c;笔者最近发现使用过程中有时候会出现卡顿现象&#xff0c;例如&#xff0c;启动软件变慢&#xff0c;打开项目的速度变慢等&#xff1a; 因此如果各位朋友觉得最近也遇到了同样的困惑&#xff0c;不妨跟着笔者一起来设置IDEA的内存大小吧~ …

虚拟现实在制造业中的应用

当你想到制造业中的虚拟现实技术时&#xff0c;你脑海中闪过的第一个念头是什么&#xff1f;从目前来看&#xff0c;只需几年时间&#xff0c;制造业就将离不开虚拟现实技术的帮助。实施虚拟现实应用对制造业来说都有诸多好处。通常情况下&#xff0c;制造设施都是由各种机器组…

基于neo4j的学术论文关系管理系统

正在为毕业设计头疼&#xff1f;又或者在学术研究中总是找不到像样的工具来管理浩瀚的文献资料&#xff1f;今天给大家介绍一款超实用的工具——基于Neo4j的学术论文关系管理系统&#xff0c;让你轻松搞定学术文献的管理与展示&#xff01;&#x1f389; 系统的核心是什么呢&a…

一个基于.NET8+WPF开源的简单的工作流系统

项目介绍 AIStudio.Wpf.AClient 是一个基于 WPF (Windows Presentation Foundation) 构建的客户端框架&#xff0c;专为开发企业级应用而设计。该项目目前版本为 6.0&#xff0c;进行了全面优化和升级&#xff0c;提供了丰富的功能和模块&#xff0c;以满足不同场景下的开发需…

清华大学《2022年+2021年822自动控制原理真题》 (完整版)

本文内容&#xff0c;全部选自自动化考研联盟的&#xff1a;《清华大学822自控考研资料》的真题篇。后续会持续更新更多学校&#xff0c;更多年份的真题&#xff0c;记得关注哦~ 目录 2022年真题 2021年真题 Part1&#xff1a;2022年2021年完整版真题 2022年真题 2021年真题…

图层之间的加减法

如右图所示&#xff0c;正方形ABCD的边长为1cm&#xff0c;AC、BD分别是以点D和点C为圆心、1cm为半径作的圆弧。问阴影部分a的面积比阴影部分b小____? 这道题首先是固定的图形&#xff0c;形状已经确定了&#xff0c;按理说a和b的面积都可以求出来&#xff0c;但是题目问的是b…

ALIGN_ Tuning Multi-mode Token-level Prompt Alignment across Modalities

文章汇总 当前的问题 目前的工作集中于单模提示发现&#xff0c;即一种模态只有一个提示&#xff0c;这可能不足以代表一个类[17]。这个问题在多模态提示学习中更为严重&#xff0c;因为视觉和文本概念及其对齐都需要推断。此外&#xff0c;仅用全局特征来表示图像和标记是不…

颐驰06持续交付,明日科技赋能出行生活

在全球智能出行领域&#xff0c;自动驾驶技术的发展一直是行业关注的焦点。不久前&#xff0c;特斯拉发布的自动驾驶出租车引发了全球关注&#xff0c;但由于缺乏具体的技术细节&#xff0c;导致投资者信心受挫&#xff0c;特斯拉股票一度下跌近10%。与此同时&#xff0c;中国车…