力扣刷题(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.mzph.cn/diannao/58168.shtml

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

相关文章

文献阅读记录5-Recent Progress in the Discovery and Design of AntimicrobialPeptides

文章名字是Recent Progress in the Discovery and Design of Antimicrobial Peptides Using Traditional Machine Learning and Deep Learning&#xff0c;24年发表 摘要 由于传统抗生素的滥用和多重耐药微生物的增加&#xff0c;抗菌药物耐药性已成为一个全球性的重大健康问…

MySQL创建库,设计表

要求&#xff1a; 根据以下需求完成图书管理系统数据库及表设计&#xff0c;并建库建表&#xff0c;并截图创建表 的详细信息(desc 表名),不用添加数据 1. 用户表: 字段: 姓名&#xff0c;用户名&#xff0c;密码&#xff0c;电话&#xff0c;住址&#xff0c;专业及年级 2. 图…

Maven 项目管理工具

目录 Maven简介 Maven快速上手 Maven详细介绍 Maven工作机制 Maven安装及配置 使用IDEA创建Maven Web工程 Maven简介 Maven是 Apache 开源组织奉献的一个开源项目&#xff0c;可以翻译为“专家”或“内行”。 Maven 的本质是一个项目管理工具&#xff0c;将项目开发和管…

华为大咖说丨如何通过反馈机制来不断优化大模型应用?

本文分享自时习知 作者&#xff1a;袁泉&#xff08;华为AI数据工程专家&#xff09;全文约3015字&#xff0c;阅读约需8分钟 大模型应用正式投入使用后&#xff0c;存在一个较为普遍的情况&#xff1a;在利用“大模型提升业务运营效率”的过程中&#xff0c;业务部门和IT团队…

K8S如何基于Istio重新实现微服务

K8S如何基于Istio重新实现微服务 认识 Istio前言Istio 的理念Istio 的架构数据平面控制平面服务与 Istio 的关系 Istio 实践环境准备安装 Helm安装Istio 使用 Istio 代理运行应用情感分析应用的架构使用 Istio 代理运行应用Sidecar 注入Ingress 网关网关资源VirtualService 资源…

动态规划 —— 路径问题-不同路径

1. 不同路径 题目链接&#xff1a; 62. 不同路径 - 力扣&#xff08;LeetCode&#xff09;https://leetcode.cn/problems/unique-paths/description/ 2. 算法原理 1. 状态表示&#xff1a;以莫一个位置为结尾 dp[i]表示&#xff1a;以[i&#xff0c;j]位置为结尾时&#xff0…

本地Docker部署开源WAF雷池并实现异地远程登录管理界面

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

[四轴飞行器] 航模常见术语

航模常见术语 1.X模式和模式 从结构形式上四轴飞行器可分为十字模式和X模式。十字模式如下图左所示&#xff0c;X模式如下图右所示。对于姿态测量和控制来说&#xff0c;两种结构差别不大。如果考虑安装航拍摄 像机&#xff0c;为了视线不被挡住&#xff0c;通常采用X模式。 …

mysql原理、部署mysql主从+读写分离、监控mysql主从脚本

mysql&#xff1a;工作原理 从库生成两个线程&#xff0c;一个I/O线程&#xff0c;一个SQL线程&#xff1b; i/o线程去请求主库 的binlog&#xff0c;并将得到的binlog日志写到relay log&#xff08;中继日志&#xff09; 文件中&#xff1b; 主库会生成一个 log dump 线程&…

2024最新保姆级Python下载安装教程

今天给大家带来Python下载安装教程&#xff01; &#x1f449;大礼包&#x1f381;&#xff1a;python安装包/pycharm教程免费分享&#xff08;安全链接&#xff0c;放心点击&#xff09;&#x1f448; 一、下载装 Python 1、进入Python官网首页&#xff0c;下载最新的Pytho…

outlook创建新账户时报错2603、2604的解决办法

全新的戴尔笔记本电脑&#xff0c;自带的Win11家庭版&#xff0c;安装ms office 2021也顺利完成。 但是奇怪的是&#xff0c;只有其中一台笔记本电脑&#xff0c;OUTLOOK无法添加新账户。 但是这个账号在WEB端登录正常&#xff0c;由于是新入职的员工&#xff0c;根据以往经验&…

transformer的新手疑问

Transformer模型的原理主要基于自注意力机制&#xff08;Self-Attention&#xff09;和编码器-解码器结构。它的设计不依赖传统的循环神经网络&#xff08;RNN&#xff09;或卷积神经网络&#xff08;CNN&#xff09;&#xff0c;而是通过并行的方式处理序列数据&#xff0c;极…

雷池社区版OPEN API使用教程

OPEN API使用教程 新版本接口支持API Token鉴权 接口文档官方没有提供&#xff0c;有需要可以自行爬取&#xff0c;爬了几个&#xff0c;其实也很方便 使用条件 需要使用默认的 admin 用户登录才可见此功能版本需要 > 6.6.0 使用方法 1.在系统管理创建API TOKEN 2.发…

REST APIs与微服务:关键差异

在构建基于微服务的应用程序时RESYful API和微服务这两个术语经常相伴出现。然而&#xff0c;它们指的是截然不同的东西。 了解 RESTful API 和微服务之间差异的最简单方式是这样&#xff1a; 微服务&#xff1a;它们是构成更大规模基于微服务的应用程序的单个服务和功能&…

《金融数据安全分级指南JR/T 0197-2020》解读与想法

#1024程序员节&#xff5c;征文# 一、文件框架与核心思考 1、定级目标再审视 自《金融数据安全 数据安全分级指南JR/T 0197-2020》&#xff08;以下简称“指南”&#xff09;发布以来&#xff0c;金融数据安全领域已历经四年的发展与变革。该指南作为金融标准中首个以“金融数…

Docker 基础入门

Docker 基础入门 前言 在云计算和微服务架构日益盛行的今天&#xff0c;软件开发与部署的效率和灵活性成为了企业竞争力的关键因素之一。Docker&#xff0c;作为一种开源的容器化平台&#xff0c;凭借其轻量级、可移植性和易于管理的特性&#xff0c;迅速成为现代软件开发和运…

[云] 大数据分析栈(Big Data Analytics Stack)+ Apache Hadoop分布式文件系统(HDFS)+Apache Spark

任务概述 本次作业旨在帮助你理解大数据分析栈&#xff08;Big Data Analytics Stack&#xff09;的工作原理&#xff0c;并通过实际操作加深认识。你将搭建Apache Hadoop分布式文件系统&#xff08;HDFS&#xff09;作为底层文件系统&#xff0c;并将Apache Spark作为执行引擎…

Linux第二讲:Linux权限理解

Linux第二讲&#xff1a;Linux权限理解 1.shell命令以及运行原理2.Linux权限2.1什么是权限2.2认识人 -- 用户、普通用户、root用户&#xff0c;以及用户之间的切换2.3文件属性2.4文件权限知识点补充2.4.1知识点一2.4.2知识点二2.4.3知识点三2.4.4知识点四 3.角色的修改4.关于权…

Puppeteer 与浏览器版本兼容性:自动化测试的最佳实践

Puppeteer 支持的浏览器版本映射&#xff1a;从 v20.0.0 到 v23.6.0 自 Puppeteer v20.0.0 起&#xff0c;这个强大的自动化库开始支持与 Chrome 浏览器的无头模式和有头模式共享相同代码路径&#xff0c;为自动化测试带来了更多便利。从 v23.0.0 开始&#xff0c;Puppeteer 进…

可私有化部署的集装箱箱号自动识别技术,提供API 接口

启智集装箱箱号自动识别技术特点&#xff1a; 集装箱箱号自动识别技术为通过手机、相机等拍摄集装箱号码后进行视频处理或图像的去燥、纠偏、二值化等分析后进行字符的识别&#xff0c;箱号识别具有以下特点&#xff1a; 1&#xff09;快速&#xff1a;自动实时识别&#xff0c…