首页 > 数据库 >数仓sql场景:迭代求结果问题

数仓sql场景:迭代求结果问题

时间:2024-08-02 17:20:12浏览次数:13  
标签:数仓 pv 迭代 union list concat sql select

1.需求

2.sql实现

这道题先需要去分析结果集,本质上是一个迭代累加的过程,先要得到如下结果

如果在面试数仓中实现了以上结果,基本上面试官会很通过,也在短时间内可以实现,实现sql如下
with tb as (
select 1 as s,'a' as pv
union all
select 2 as s,'b' as pv
union all
select 3 as s,'c' as pv
union all
select 4 as s,'d' as pv
union all
select 5 as s,'e' as pv
union all
select 6 as s,'f' as pv
)

select s,pv,concat_ws('+',collect_list(re1) OVER (ORDER BY s ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)) from 
(select *,concat_ws('+',collect_list(pv) OVER (ORDER BY s ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)) as re1 from tb) tb1;
首先开窗将pv分组连接起来作为一个结果集,然后再将结果集分组连接起来。核心知识点:collect_list,concat_ws,开窗函数及开窗中的ROWS BETWEEN。其中`ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW`为开始行到当前行

另一种实现方式,通过不断解析实现,分组实现,这种实现主要考察对sql的深度理解和组装,实现起来还是比较复杂的,sql如下
with tb as (
select '1' as s,'a' as pv
union all
select '2' as s,'b' as pv
union all
select '3' as s,'c' as pv
union all
select '4' as s,'d' as pv
union all
select '5' as s,'e' as pv
union all
select '6' as s,'f' as pv
),
tb1 as 
(select *,
concat_ws(',',collect_list(pv) OVER (ORDER BY s ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)) as pv_n,
reverse(concat_ws(',',collect_list(s) OVER (ORDER BY s ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW))) as s_n 
from tb),
tb2 as 
(select s,pv,pv_n,s_n from tb1 
lateral view explode(SPLIT(pv_n,',')) tb1 as pv_n),
tb3 as 
(select *,row_number() over(partition by s order by pv_n) as rn from tb2)
select s,pv,concat_ws('+',collect_list(concat(pv_n,'*',split(s_n,',')[rn-1]))) as res from tb3 group by s,pv order by s;
该种实现方式包含的知识点比较多,包括collect_list,concat_ws,lateral view explode,开窗函数。其中将开窗出来的值作为切割出来的数组下标来使用这种思路在实际中不容易想到。但这个sql本质上有隐患,其中reverse函数如果s字段超过个位数后存在问题,当做练sql吧 实际中要多想想

上图中,要取pv_n*s_n[rn-1],然后再将结果连接起来

然后再分组连接起来

标签:数仓,pv,迭代,union,list,concat,sql,select
From: https://www.cnblogs.com/jiashengmei/p/18339180

相关文章

  • PgStatement的executeCachedSql(String sql, int flags, String @Nullable [] column
    方法代码如下:privatebooleanexecuteCachedSql(Stringsql,intflags,String@Nullable[]columnNames)throwsSQLException{//第一部分PreferQueryModepreferQueryMode=connection.getPreferQueryMode();booleanshouldUseParameterized=false;......
  • SQL进阶技巧:Hive如何巧解和差计算的递归问题?【应用案例2】
    目录0问题描述1数据准备2问题分析3小结 0问题描述有如下数据:反应了每月的页面浏览量现需要按照如下规则计算每月的累计阅读量,具体计算规则如下:最终结果如下:1数据准备withdataas(select'2024-01'asmonth,2aspvunionallselect'2024-02'asm......
  • 如何在mysql中删除重复数据
    #分组去重法讲重复的列进行分组之后用min(id)#取其中最小的保留,其余的删除--步骤1:创建临时表,保存每组最小的IDCREATETEMPORARYTABLEtmp_keep_idsASSELECTMIN(id)ASidFROM重复表名GROUPBY重复列;--步骤2:删除原表中不在临时表中的记录DELETEFROM原表......
  • 达梦数据库系列—44.SQL调优
    目录SQL优化思路1、定位慢sql2、SQL分析方法2.1执行计划2.2ET工具2.3dbms_sqltune工具3、SQL语句优化3.1索引3.2SQL语句改写3.3表设计优化3.4表的连接方式3.5HINT4、统计信息SQL优化思路1、定位慢sql待优化的SQL大致可分为两类:1、SQL执行时间在十......
  • Springboot Docker Redis Mysql集成
    尽管网上关于SpringbootDockerRedisMysql集成的文档很多,但是很多都是老文档,问题不少,所以我专门整理了这份文档。我家里的笔记本是mac,所以我就在mac上详细说明下我的搭建过程。首先我们需要安装docker,mac上本来就有docker的安装包,因此对于mac来说,安装docker就是一件比较轻松的......
  • MySQL:初识数据库&初识SQL&创建数据库
    目录1、初识数据库1.1什么是数据库1.2 什么是MySQL2、数据库2.1 数据库服务&数据库2.2C/S架构3、初识SQL3.1什么是SQL3.2 SQL分类 4、使用SQL4.1查看所有数据库4.1.2语句解析 4.2创建数据库4.2.1 ifnotexists校验 4.2.2手动明确字符集和排序规......
  • 基于Java+SpringBoot+Mysql+Vue实现的4S店保养与维修系统部分功能设计与实现八
    一、前言介绍:1.1项目摘要随着社会经济的不断发展,人们对汽车养护和维修的重视程度日益提高。然而,传统的汽车保养与维修服务存在诸多问题,如信息不对称、服务质量参差不齐等。这些问题不仅影响了消费者的服务体验,也制约了汽车后市场的健康发展。因此,为了解决这些问题,提升汽......
  • 基于Java+SpringBoot+Mysql+Vue实现的4S店保养与维修系统部分功能设计与实现九
    一、前言介绍:1.1项目摘要随着社会经济的不断发展,人们对汽车养护和维修的重视程度日益提高。然而,传统的汽车保养与维修服务存在诸多问题,如信息不对称、服务质量参差不齐等。这些问题不仅影响了消费者的服务体验,也制约了汽车后市场的健康发展。因此,为了解决这些问题,提升汽......
  • sql更新数据库表的某一字段每条记录的随机数
    sql更更新数据库表的某一字段每条记录的随机数(6位随机数)使用游标实现,以下代码在SQL里执行即可--声明游标DECLARE@user_idvarchar(36)DECLAREuser_extension_cursorCURSORFORSELECTid--表里唯一识别ID(改为自己表里的字段名)FROM[test].[dbo].[my_table]--表名......
  • sqli-labs-master less1-less6
    目录通关前必看1、判断是否存在sql注入以及是字符型还是数值型:2、各种注入方式以及方法有回显型:报错注入(只有'ok'和'no'的提示以及报错提示):详细思路,后面的题都可以这样去思考关卡实操less1less2less3less4less5less6通关前必看在这之前,需要掌握数据库的基本......