SQL | 窗口函数 row number + partition by 排序

article/2025/9/19 6:41:55

窗口函数 row number + partition by 排序

  • 1 背景
  • 2 SQL牛逼函数走起来
    • 2.1 Step1
    • 2.2 SQL实现1
    • 2.3 Step2
    • 3.4 SQL实现2
    • 2.5 补充-collect函数
  • 3 头条面试SQL题
    • 3.1 题目
    • 3.2 实现
    • 3.2 建表

1 背景

今天实习学到了一个很牛逼的sql函数,而且解决了一个之前面试头条时候的SQL问题!(也知道了为啥头条挂了…毕竟当时SQL做错了)

  • 前一篇关于SQL的推文(给链接)最后形成的表是这样的:
import pandas as pd
df = pd.read_excel('./sql数据处理与提取-窗口函数-0327.xlsx', sheet_name='interest0')
df
deviceidcategoryinterestinterests1interests_newsinterests_score
065762973军事:1.0,娱乐:0.917,军事/装备:0.916,娱乐/明星八卦:0.874,历史/古...体育/冰雪运动:0.641体育/冰雪运动0.641
1774830731历史/古代史:1.0,历史:0.5历史/古代史:1.0历史/古代史1.000
265762973军事:1.0,娱乐:0.917,军事/装备:0.916,娱乐/明星八卦:0.874,历史/古...人文/人文科普:0.584人文/人文科普0.584
3124901984情感/两性:1.0,历史/古代史:0.933,娱乐:0.901,情感:0.742,体育/乒乓...体育/NBA:0.566体育/NBA0.566
4874657455体育/国际足球:9.063,体育/中国足球:3.019,娱乐/综艺:1.947,体育/NBA...体育/乒乓球:0.207体育/乒乓球0.207

现在的需求是这样:

  • 计算每一个deviceid下interests_score前三以及对应的interests_news
  • 并且interests_news的前面的标签不能有“娱乐” “要闻” “社会”
  • 根据第二步拆开之后,如果后面为空,即没有联合标签,取前面的,非空则取后面的。

2 SQL牛逼函数走起来

2.1 Step1

  • Step1:使用pslit函数根据反斜杠将interests_news进行切分为tag_1和tag_2

2.2 SQL实现1

(selectdeviceid,interests_news,split(interests_news,'/')[0] as tag_1,split(interests_news,'/')[1] as tag_2, interests_scorefrom(selectdeviceid,categoryinterest,interests1,split(interests1, ':')[0] as interests_news,split(interests1, ':')[1] as interests_scorefrom(selectdeviceid,categoryinterest,interests1fromtable1lateral view explode(split(categoryinterest,',')) tb1 as interests1whereday=20190313group bydeviceid,categoryinterest,interests1)t1)t2whereinterests_score>=0.5 and interests_score<=1 --获取高分值兴趣点group bydeviceid,interests_news,split(interests_news,'/')[0] ,split(interests_news,'/')[1],interests_score-- 疑问 为啥没有直接用tag_1 tag_2 )interests0

2.3 Step2

Step2:均在select中实现!+ where限制

  • 并且舍弃tag_1为“娱乐” “要闻” “社会”三类的 where判断
  • 合并tag_1与tag_2 使用case when 如果tag_2非空则取tag_2 否则取tag_1
  • 使用row number函数 + partition by + order by 并且取排名前三 where

3.4 SQL实现2

selectdeviceid,interests_score,tag_type
--	collect_set(tag_type)as interests_array --行转纵
from(select 	deviceid,interests_news,interests_score,case when tag_2 is not null then tag_2 when tag_2 is null then tag_1 end as tag_type,--二级标签不为空取二级标签值,若二级为空,则取一级标签row_number() over(partition by deviceid order by interests_score desc) rank --对单个用户,按照分值降序-- 表示根据deviceid分组,在分组内部根据 interests_score 降序,而此函数计算的值就表示每个id内部根据score排序后的顺序编号记为rank(组内连续的唯一的)from(selectdeviceid,interests_news,split(interests_news,'/')[0] as tag_1,split(interests_news,'/')[1] as tag_2, interests_scorefrom(selectdeviceid,categoryinterest,interests1,split(interests1, ':')[0] as interests_news,split(interests1, ':')[1] as interests_scorefrom(selectdeviceid,categoryinterest,interests1fromportal.ddm_user_multiprod_user_portrait_dlateral view explode(split(categoryinterest,',')) tb1 as interests1whereday=20190313group bydeviceid,categoryinterest,interests1)t1)t2whereinterests_score>=0.5 and interests_score<=1 --获取高分值兴趣点group bydeviceid,interests_news,split(interests_news,'/')[0] ,split(interests_news,'/')[1],interests_score-- 疑问 为啥没有直接用tag_1 tag_2 )interests0wheretag_1 not in ('娱乐','社会','要闻','未知') --去除主流兴趣标签影响)interests00whererank<=4 --获取几类二级标签的组合 取top4
group bydeviceid,interests_score,tag_type
  • 结果为:
df = pd.read_excel('./sql数据处理与提取-窗口函数-0327.xlsx', sheet_name='step3')
df
deviceidinterests_newstag_typeinterests_scorerank
065762973体育/冰雪运动冰雪运动0.6411
165762973人文/人文科普人文科普0.5842
2774830731历史/古代史古代史1.0001
3124901984体育/NBANBA0.5661
4874657455体育/乒乓球乒乓球0.2071

总结:

  • row number()函数特别好用 往往配合 partition by 以及 order by
    参考:https://www.cnblogs.com/icebutterfly/archive/2009/08/05/1539657.html

  • 上述函数适用情况:当需要根据某一个标签进行分组并且在组内需要根据另一个字段进行降序or升序排列 打上排名 视情况取前几名 【下面还会举一个头条面试的例子】

  • case when函数语句:使用在select语句中,并且是

    case when *** then *** when *** then *** (else *** ) end as 新字段名称

2.5 补充-collect函数

作用:用来多行转为一行的方法 它返回一个消除了重复元素的对象集合, 其返回值类型是 array 。

SQL语句:

select deviceid, collect_set(tag_type) as interests_array 
from 上述表
  • 结果为:
deviceidinterests_array
065762973["冰雪运动", "人文科普"]
1774830731["古代史"]
2124901984["NBA"]
3874657455["乒乓球"]

3 头条面试SQL题

3.1 题目

前段时间找实习去头条面试,最后被虐的体无完肤…其中面试官灵魂拷问:你SQL咋样?如果1-10分,你给自己的SQL打几分?我当时内心就无语了!?还有这种操作?嗨呀,SQL当时完全自学,当时没有实习,没有任何场景应用,所以水平明显很次,内心TMD脸上笑嘻嘻的说:6分,及格吧。面试官同样皮笑肉不笑的说,好,那我出个题哈,(面试官内心os:小样,那我就出个6分水平的题,看你答不答得出来!)

题目是这样的:
现在有一张表,有三列,一列是学生的姓名,一列是学生的雅思考试成绩,一列是考试时间,学生可以多次参加雅思考试,现在想要统计出不同学生最近一次考试时间的成绩!你说说思路吧!

3.2 实现

嗨呀,当时稍微想了一下,感觉不难嘛,于是脱口而出:

select name, score, max(time) from table group by name 

当时信心满满,但是回来和同学一聊,有说对的有说错的,尴尬!直到今天在公司遇到一个和这个很类似的问题啊!于是请教了我的leader,并且当场给我建了个临时表show了一把,结果是我错了,这种方法是不对的!

正确答案现在来看,肯定不难了:

  • 首先取出三列,然后使用row number函数 根据姓名进行partition by 然后对时间进行降序排列 取rank小于等于1的即可
select *, 
Row_Number() over (partition by name order by time desc) rank 
from IELTS
where rank <= 1

那当时的做法对不对呢?废话不多话,建一个表试试!

3.2 建表

在这里插入图片描述

结果为:

在这里插入图片描述
注:这次的代码刚在本机竟然没有跑通,后天去公司再请教下leader…不过逻辑肯定是没问题的~

未完待续


0716更新:后续请参考博客:SQL | 关于窗口函数的补充


http://chatgpt.dhexx.cn/article/0gg1HyPy.shtml

相关文章

pandas 实现sql row number 功能

1. pandas 实现sql row number 功能 先按照id和msg_ts排序&#xff0c; 然后按照id topic分组&#xff0c;row number功能就现实了 df[row_num] df.sort_values([id, msg_ts], ascendingTrue).groupby([id, topic]).cumcount() 1 padans链接&#xff1a; https://pandas.…

ROW_NUMBER 用法小结

ROW_NUMBER函数是返回结果集分区内行的序列号&#xff0c;每个分区的第一行从 1 开始。 CREATE TABLE [dbo].[tb_Seller]([编号] [nvarchar](50) NULL,[商品名称] [nvarchar](50) NULL,[销售额] [money] NULL,[利润] [money] NULL,[门店名称] [nvarchar](50) NULL,[日期] [sma…

ROW_NUMBER() OVER()函数用法详解 (分组排序 例子多)

语法格式&#xff1a;row_number() over(partition by 分组列 order by 排序列 desc) row_number() over()分组排序功能&#xff1a; 在使用 row_number() over()函数时候&#xff0c;over()里头的分组以及排序的执行晚于 where 、group by、 order by 的执行。 例一&#…

Row_number()函数用法

Row_number()函数是SQL SERVER系统函数中的一种&#xff0c;它为结果集的分区中的每一行分配一个连续的整数。简单的说就是生成一个独表&#xff0c;序号以每个分区的第一行开头&#xff0c;下面是其基本语法&#xff1a; PARTITION BY子句将结果集划分为分区。 ROW_NUMBER()…

SQL Server中row_number函数用法介绍

一、SQL Server Row_number函数简介 ROW_NUMBER()是一个Window函数&#xff0c;它为结果集的分区中的每一行分配一个连续的整数。 行号以每个分区中第一行的行号开头。 语法实例&#xff1a; select *&#xff0c;row_number() over(partition by column1 order by column2)…

SQL中row_number函数用法

row_number函数用法 1、函数讲解2、LeetCode实战 1、函数讲解 语法&#xff1a;ROW_NUMBER() OVER(PARTITION BY COLUMN ORDER BY COLUMN)简单的说&#xff0c;row_number()从1开始&#xff0c;为每条分组记录返回一个数字&#xff0c;举例&#xff1a; ROW_NUMBER() OVER(OR…

如何查看Vue项目vue的版本号

如果是用vue-cli创建的项目&#xff0c;则找到项目根目录下的"package.json"文件 如果是要查看vue-cli的版本号的话&#xff0c;则键盘WinR&#xff0c;输入cmd&#xff0c;再在cmd里面输入vue -V

查看vue版本号

查看npm安装包的版本号&#xff0c;一般情况是都是执行&#xff1a; 包名 --version 或 包名 -V。 当执行vue --version时&#xff0c;如果安装了vue/cli 那么得到的是vue/cli的版本&#xff0c;而不是vue的。 所以正确查看方式是执行&#xff1a; npm list vue如图所示&…

uni-app中查看vue的版本号

1.查看vue的版本号 在manifest.json 文件中&#xff0c;基础配置的底部有vue版本的配置

如何查看vue版本号以及vue/cli脚手架版本号

查看vue版本号 方法一&#xff1a;直接在项目的package.json文件&#xff0c;找到dependencies就能看到了 方法二&#xff1a;输入命令npm ls vue (或者npm list vue) 查看vue/cli脚手架版本号 方法&#xff1a;输入命令vue -V (或者vue --version&#xff09;

vue cli更换版本

vue-cli更换版本 vue更换版本 最近要写个小项目&#xff0c;用到了vue&#xff0c;于是安装了vue cli&#xff0c;但是在使用过程中发现最新的版本好像不太好用&#xff0c;想换成旧版本。 查看当前版本 通过vue -V可以查看当前版本&#xff0c;现有版本是5.0.8&#xff0c…

查看vue版本,cli版本,npm以及node版本

1.查看vue版本 package.json 文件中2.查看vue-cli版本 命令&#xff1a; vue -V3.查看npm版本 命令&#xff1a; npm -v4.查看node版本 命令&#xff1a; node -v5.自测版本号截图

查看vue版本号、vue-cli版本号

查看vue版本号 方法一&#xff1a;npm ls vue方法二&#xff1a;package.json查看vue-cli版本号 vue -V两者不要搞混哦

vue -V查看vue版本时,提示vue.js缺少标识符

vue -V查看vue版本时&#xff0c;提示vue.js缺少标识符 出现的错误提示如下图。 我的解决办法&#xff1a; winR打开 cmd 输入 where vue。 找到D:\a_tools\vue,删除该文件夹中的vue.js。 重新输入vue -V 查看版本号。

查看vue版本和vue脚手架版本

打开cmd控制台&#xff1a; 输入vue --version&#xff08;俩个-&#xff09;或 vue -V&#xff08;第二个V要大写&#xff09;查看vue脚手架版本&#xff1b; 输入npm list vue -g 查看vue版本和vue脚手架版本&#xff1b;

如何查看vue版本号

如何查看vue版本号 先来看一个错误示范 在cmd控制台内&#xff0c;输入npm -v 可查看到npm 的版本号&#xff1b; vue -V 可看到vue的版本号。 这个是vue脚手架的版本号。 来看正确的方式 npm list vue在控制台输入上述3个单词

查看vue的版本命令,以及vue脚手架的版本命令

查看vue版本的命令&#xff1a; 【 害我找了半天&#xff01;&#xff01;&#xff01; 谁不知道-version啊&#xff0c;一天天净发些没用的 】 npm list vue 脚手架版本命令&#xff0c;这个大家倒是都知道 vue -V 或者 vue --version 升级vue至最新版本&#xff1a; 【vue3.…

如何查看 当前安装的vue版本

目录 1 实现 1 实现 要查看当前安装的 Vue 版本&#xff0c;可以使用以下方法&#xff1a; 在终端或命令提示符中运行以下命令&#xff1a; vue --version如果你使用的是 Vue CLI 创建的项目&#xff0c;可以在项目的根目录中找到 package.json 文件。在该文件中&#xff0c…

Vue相关配置版本的查看

一、查看Vue的版本 1.查看全局vue的版本 npm info vue注&#xff1a;npm info vue 和 npm info vue version 都可行 2.查看项目中vue的版本&#xff08;局部vue的版本&#xff09; npm list vue version注&#xff1a;npm list vue version 或者 npm list vue 都是可以的…

查看前端Vue版本命令

阅文时长| 0.43分钟字数统计| 689.6字符主要内容| 1、引言&背景 2、解决方案 3、声明与参考资料 『查看前端Vue版本命令』编写人| SCscHero 编写时间| 2022/1/5 PM6:33文章类型| 系列完成度| 已完成座右铭每一个伟大的事业&#xff0c;都有一个微不足道的开始。 一、引言&…