记一次postgresql拼接函数string_agg() 和row_number() 使用

PG两个函数使用需求和简单介绍

  • 需求背景介绍
    • 第一个需求背景是这样的
    • 需求升级一下
    • 接下来讲讲STRING_AGG()
      • 基本语法
      • 排序
    • 然后我们再说说ROW_NUMBER()
      • 基本语法
      • 使用 row_number() over (partition by) 进行分组统计
      • 使用 row_num限定每组数量

需求背景介绍

第一个需求背景是这样的

我需要从数据库查询企业的一些信息,其中包括企业曾用名,企业曾用名可能有多个,但是企业主体信息只有一个,且不在同一张表中;我还需要取出另一个表中关联的电话和邮箱,其中电话和邮箱有多个,实际为年份不同可能不一样,也可能为空,我需要取不为空的最新年份的数据。
数据库PG,要求所有曾用名,分隔,企业查询为模糊查询。

SELECTC.entname as entname,C.uniscid as uniscid,cb.dom as dom,cb.esdate as esdate,cb."name" as frname,cb.regcap as regcap,STRING_AGG ( cm.altbe, ',' ) as nameBefore,A.email as email,A.tel as tel,co.name as entstatusFROMcompanyC LEFT JOIN company_basic cb ON C.entid = cb.entidLEFT JOIN company_modify cm ON C.entid = cm.entidleft join code_ex02 co on cb.entstatus = co.codeLEFT JOIN (SELECTcc.entid AS entid,ca.email AS email,ca.tel AS tel,ROW_NUMBER () OVER ( PARTITION BY cc.ID ORDER BY ca.email DESC ) AS rnFROMcompany ccLEFT JOIN company_ar ca ON cc.entid = ca.entidWHEREcc.entname LIKE concat('%',#{companyName},'%')AND ca.email IS NOT NULLAND ca.tel IS NOT NULLORDER BYca.ancheyear DESC) A ON C.entid = A.entid AND A.rn = 1WHEREC.entname LIKE concat('%',#{companyName},'%')AND cm.altitem = '01'GROUP BYC.entname,C.uniscid,cb.dom,cb.esdate,cb."name",cb.regcap,A.email,A.tel,co.name

可以看到,关联company_ar表,查曾用名,需要使用row_number()函数,取第一行,这就需要先包一层,取rn=1
这里为什么不能使用limit 1,原因是这里是模糊查询,查出来的是多家公司,我需要每个公司取第一行,limit 1不能满足。


需求升级一下

我需要从数据库查询企业的一些信息,其中包括企业曾用名,企业曾用名可能有多个,且是分开的,数据大概像下图
既有可能有多个,每个还都是分开的,需要拼接,每个完整的企业曾用名使用,分隔,但是企业主体信息只有一个,且不在同一张表中;我还需要取出另一个表中关联的电话和邮箱,其中电话和邮箱有多个,实际为年份不通可能不一样,也可能为空,我需要取不为空的最新年份的数据。
数据库PG,要求所有曾用名先按照id排序之后拼接再,分隔,企业查询为模糊查询。

在这里插入图片描述

SELECTC.entname as entname,C.uniscid as uniscid,C.dom as dom,C.esdate as esdate,C."name" as frname,C.regcap as regcap,STRING_AGG ( C.content_text, ',' ) as nameBefore,C.email as email,C.tel as tel,c.entstatus as entstatusFROM(SELECTC.entname,C.uniscid,cb.dom,cb.esdate,cb."name",cb.regcap,STRING_AGG ( ccrc.content_text, '' ORDER BY ccrc.ID ) AS content_text,A.email,A.tel,cb.entstatus as entstatusFROMcompanyC LEFT JOIN company_basic cb ON C.ID = cb.entidLEFT JOIN company_change_record ccr ON ccr.entid = C.IDAND ccr.altitem = '名称变更'LEFT JOIN company_change_record_content ccrc ON ccr.ID = ccrc.company_change_record_idAND ccrc.company_chang_type = 0LEFT JOIN (SELECTcc.ID AS ID,ca.email AS email,ca.tel AS tel,ROW_NUMBER () OVER ( PARTITION BY cc.ID ORDER BY ca.email DESC ) AS rnFROMcompany ccLEFT JOIN company_ar ca ON cc.ID = ca.entidWHEREcc.entname LIKE concat('%',#{companyName},'%')AND ca.ancheyear IS NOT NULLAND ca.email IS NOT NULLAND ca.tel IS NOT NULLORDER BYca.ancheyear DESC) A ON A.ID = C.IDAND A.rn = 1WHEREC.entname LIKE concat('%',#{companyName},'%')GROUP BYC.entname,C.uniscid,cb.dom,cb.esdate,cb."name",cb.regcap,A.email,A.tel,cb.entstatus,ccrc.company_change_record_id) CGROUP BYC.entname,C.uniscid,C.dom,C.esdate,C."name",C.regcap,C.email,C.tel,c.entstatus

这个sql写起来就比之前的sql又多一层,曾用名字段需要拼接两次,且企业曾用名拼接是需要按照id排序的。

接下来讲讲STRING_AGG()

基本语法

string_agg(column_name, separator)  

前边column_name是想要拼接的字段名,后边separator是分隔符。
像上边sql中

STRING_AGG ( C.content_text, ',' )

将content_text 以,分隔
使用像string_agg() 聚合函数,需要使用group by将不需要聚合的字段都写在group by中。

排序

这里升级版需求需要排序然后再聚合拼接,就需要加上order by
这里直接在函数中加上就可以

STRING_AGG ( ccrc.content_text, '' ORDER BY ccrc.ID )

这样就可以实现。

然后我们再说说ROW_NUMBER()

row_number() 函数是 PostgreSQL 中的一个窗口函数,它的作用是为每一行分配一个唯一的序号。当涉及到分组统计时,我们可以使用 row_number() 函数结合 over (partition by) 子句来实现。

基本语法

ROW_NUMBER() OVER ([PARTITION BY partition_expression, ... ]ORDER BY sort_expression [ASC | DESC], ...
)

partition_expression需要是唯一ID,order by 按照自己的实际需求

使用 row_number() over (partition by) 进行分组统计

像上边sql中,

ROW_NUMBER () OVER ( PARTITION BY cc.ID ORDER BY ca.email DESC 

我们首先使用 PARTITION BY cc.ID 对数据进行分组,然后使用 ORDER BY email DESC 对每个分组内的数据按照邮箱(其实是随便选的,因为这里需求不做强制要求)降序排序。接着,我们使用 ROW_NUMBER() 函数为每一行分配一个唯一的序号。最后,我们将结果输出到一个新的表中。

使用 row_num限定每组数量

像上边sql中,已经对结果进行了分组统计

ROW_NUMBER () OVER ( PARTITION BY cc.ID ORDER BY ca.email DESC 

最终关联的时候取rn = 1,就可以限定数量,这里可以使用<= 等等限定数量。

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

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

相关文章

【MATLAB源码-第222期】基于matlab的改进蚁群算法三维栅格地图路径规划,加入精英蚁群策略。包括起点终点,障碍物,着火点,楼梯。

操作环境&#xff1a; MATLAB 2022a 1、算法描述 蚁群算法&#xff08;Ant Colony Optimization&#xff0c;ACO&#xff09;是一种通过模拟蚂蚁觅食行为的启发式优化算法。它由意大利学者Marco Dorigo在20世纪90年代初提出&#xff0c;最初用于解决旅行商问题&#xff08;T…

从《千脑智能》看大模型

千脑智能与大模型 千脑智能介绍 世界模型千脑智能理论——对大脑的全新理解旧大脑&#xff1a;演化的历史烙印新大脑&#xff1a;智慧的创新引擎新旧大脑的互动与争斗启示与借鉴 大脑对信息的处理和建模六根六尘六识 新脑&#xff1a;智能的创新中枢旧脑&#xff1a;生存的本能…

Spring的Controller是单例还是多例,如何保证线程安全的。

目录 验证是否单例&#xff08;默认单例&#xff09; 多例测试 单例对象成员变量测试 多例对象成员变量测试 解决方案 结论&#xff1a; 补充说明 答案&#xff1a;controller默认是单例的&#xff0c;不要使用非静态的成员变量&#xff0c;否则会发生数据逻辑混乱。 正…

求宇文玥在水下的浮力和赵丽颖捞他的时间

关注微信公众号 数据分析螺丝钉 免费领取价值万元的python/java/商业分析/数据结构与算法学习资料 2024年汉东省在达康书记的带领下率先实现高考试点改革。为让更多的考生能提升对他们的理解和记忆&#xff0c;把电视剧的场景融入考试题目中。确保学生看一遍就懂&#xff0c;想…

STM32 proteus + STM32Cubemx仿真教程(第一课LED教程)

文章目录 前言一、STM32点亮LED灯的原理1.1GPIO是什么1.2点亮LED灯的原理 二、STM32Cubemx创建工程三、proteus仿真电路图四、程序代码编写1.LED灯操作函数介绍HAL_GPIO_WritePin函数原型参数说明示例代码 HAL_GPIO_TogglePin函数原型参数说明示例代码 2.代码编写3.烧写程序 总…

(三)React事件

1. React基础事件绑定 语法&#xff1a; on 事件名称 { 事件处理程序 }&#xff0c;整体上遵循驼峰命名法 App.js //项目根组件 //App -> index.js -> public/index.html(root)function App() {const handleClick () > {console.log(button被点击了)}return (<…

k8s学习--kubernetes服务自动伸缩之水平收缩(pod副本收缩)VPA详细解释与安装

文章目录 前言VPA简介简单理解详细解释VPA的优缺点优点1.自动化资源管理2.资源优化3.性能和稳定性提升5.成本节约6.集成性和灵活性 缺点1.Pod 重启影响可用性2.与 HPA 冲突3.资源监控和推荐滞后&#xff1a;4.实现复杂度&#xff1a; 核心概念Resource Requests 和 Limits自动调…

AI大模型学习(非常详细)零基础入门到精通,收藏这一篇就够了

前言 随着人工智能技术的快速发展&#xff0c;AI大模型学习正成为一项备受关注的研究领域。为了提高模型的准确性和效率&#xff0c;研究者们需要具备深厚的数学基础和编程能力&#xff0c;并对特定领域的业务场景有深入的了解。通过不断优化模型结构和算法&#xff0c;AI大模…

python如何输入回车

Python默认遇到回车的时候&#xff0c;输入结束。所以我们需要更改这个提示符&#xff0c;在遇到空行的时候&#xff0c;输入才结束。 raw_input就是从标注输入读取输入&#xff0c;输入的是什么就是什么。 文档解释&#xff1a; The function then reads a line from input,…

UFS协议入门-分层结构

写在前面:本文参考UFS jedec3.1,本文思维导图如下 1. 分层概述 UFS协议分为3层,从上至下分别是:应用层(UAP),传输层(UTP),互联层(UIC),具体结构如下图所示。 2.1 应用层 在应用层(UAP)中,包括:UFS指令集(UCS),设备管理器(Device Manager),任务管理器(Task Manager…

基于FPGA的图像一维FFT变换IFFT逆变换verilog实现,包含tb测试文件和MATLAB辅助验证

目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 5.算法完整程序工程 1.算法运行效果图预览 fpga仿真结果 matlab调用FPGA的仿真结果进行图像显示 2.算法运行软件版本 vivado2019.2 matlab2022a 3.部分核心程序 ......................…

Knife4j 生成 API 文档

文章目录 Knife4j 简介使用步骤Knife4j 常用注解的列表案例可能遇到报错 Knife4j 简介 Knife4j 是一个增强的 Swagger 文档生成工具&#xff0c;提供了更加友好的界面和更多功能&#xff0c;使得 API 文档更加美观且易于使用。它是基于 Spring Boot 和 Swagger 进行封装的&…

Xcode 安装17.5 simulator 总是失败

升级到xcode15.4后需要安装ios17.5模拟器 但是在下载过程中会遇到报错 : The network connection is lost 解决方案&#xff1a; 先将模拟器下载到本地 Xcode 安装17.5 simulator 下载地址&#xff1a; Sign In - Applhttps://developer.apple.com/download/all/?qXcode 下…

C# WPF入门学习主线篇(十五)—— DockPanel布局容器

C# WPF入门学习主线篇&#xff08;十五&#xff09;—— DockPanel布局容器 欢迎来到C# WPF入门学习系列的第十五篇。在前几篇文章中&#xff0c;我们探讨了 Canvas、StackPanel 和 WrapPanel 布局容器及其使用方法。本篇博客将介绍另一种强大且常用的布局容器——DockPanel。…

【计算机网络】P3 计算机网络协议、接口、服务的概念、区别以及计算机网络提供的三种服务方式

目录 协议什么是协议协议是水平存活的协议的组成 接口服务服务是什么服务原语 协议与服务的区别计算机网络提供的服务的三种方式面向连接服务与无连接服务可靠服务与不可靠服务有应答服务与无应答服务 协议 什么是协议 协议&#xff0c;就是规则的集合。 在计算机网络中&…

# 梯影传媒T6投影仪刷机方法及一些刷机工具链接

梯影传媒T6投影仪刷机方法及一些刷机工具链接 文章目录 梯影传媒T6投影仪刷机方法及一些刷机工具链接1、安装驱动程序2、备份设备rom【boot、system】3、还原我要刷进设备的rom【system】4、打开开发者模式以便于安装apk5、root设备6、更多好链接&#xff1a; 梯影传媒T6使用的…

Redis系列-4 Redis集群介绍

Redis集群 Redis提供了持久化能力&#xff0c;保证了重启不会丢失数据&#xff1b;但Redis重启至完全恢复期间&#xff0c;缓存不可用。另外&#xff0c;对于高并发场景下&#xff0c;单点Redis服务器的性能不能满足吞吐量要求&#xff0c;需要进行横向扩展。此时&#xff0c;…

软件设计,建模及需求分析

文章目录 设计原则建模及需求分析UML画图工具原型图画图工具 重构 设计原则 SOLID原则 单一职责 开闭 &#xff08;扩展开放&#xff0c;修改关闭&#xff09; 里氏替换 &#xff08;父类出现地方都可以用子类替换&#xff09; 接口隔离 依赖倒置&#xff08;高层模块不依…

cmake使用make和Ninja构建对比

前提 make和Ninja是两个常见的构建工具&#xff0c;在网上查阅了一些资料&#xff0c;说是Ninja比make构建速度要快很多。但是具体不知道快多少&#xff0c;所以趁着这次编译clang的机会&#xff0c;分享下它们在时间方面差多少。 步骤 下载llvm 参考llvm官网&#xff0c;这…