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

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

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

需求背景介绍

第一个需求背景是这样的

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

SELECT
            C.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 entstatus
        FROM
            company
            C LEFT JOIN company_basic cb ON C.entid = cb.entid
            LEFT JOIN company_modify cm ON C.entid = cm.entid
            left join code_ex02 co on cb.entstatus = co.code
            LEFT JOIN (
        SELECT
            cc.entid AS entid,
            ca.email AS email,
            ca.tel AS tel,
            ROW_NUMBER () OVER ( PARTITION BY cc.ID ORDER BY ca.email DESC ) AS rn
        FROM
            company cc
            LEFT JOIN company_ar ca ON cc.entid = ca.entid
        WHERE
            cc.entname LIKE concat('%',#{companyName},'%')
            AND ca.email IS NOT NULL
            AND ca.tel IS NOT NULL
        ORDER BY
            ca.ancheyear DESC
            ) A ON C.entid = A.entid AND A.rn = 1
        WHERE
            C.entname LIKE concat('%',#{companyName},'%')
            AND cm.altitem = '01'
        GROUP BY
            C.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排序之后拼接再,分隔,企业查询为模糊查询。

在这里插入图片描述

SELECT
            C.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 entstatus
        FROM
            (
        SELECT
            C.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 entstatus
        FROM
            company
            C LEFT JOIN company_basic cb ON C.ID = cb.entid
            LEFT JOIN company_change_record ccr ON ccr.entid = C.ID
            AND ccr.altitem = '名称变更'
            LEFT JOIN company_change_record_content ccrc ON ccr.ID = ccrc.company_change_record_id
            AND ccrc.company_chang_type = 0
            LEFT JOIN (
        SELECT
            cc.ID AS ID,
            ca.email AS email,
            ca.tel AS tel,
            ROW_NUMBER () OVER ( PARTITION BY cc.ID ORDER BY ca.email DESC ) AS rn
        FROM
            company cc
            LEFT JOIN company_ar ca ON cc.ID = ca.entid
        WHERE
            cc.entname LIKE concat('%',#{companyName},'%')
            AND ca.ancheyear IS NOT NULL
            AND ca.email IS NOT NULL
            AND ca.tel IS NOT NULL
        ORDER BY
            ca.ancheyear DESC
            ) A ON A.ID = C.ID
            AND A.rn = 1
        WHERE
            C.entname LIKE concat('%',#{companyName},'%')
        GROUP BY
            C.entname,
            C.uniscid,
            cb.dom,
            cb.esdate,
            cb."name",
            cb.regcap,
            A.email,
            A.tel,
            cb.entstatus,
            ccrc.company_change_record_id
            ) C
        GROUP BY
            C.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,就可以限定数量,这里可以使用<= 等等限定数量。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【传知代码】BLIP - VLP任务的新框架(论文复现)

前言&#xff1a;在当今人工智能与机器学习领域&#xff0c;视觉-语言预训练&#xff08;Vision-and-Language Pre-training, VLP&#xff09;任务正逐渐崭露头角&#xff0c;其对于推动跨模态智能系统的进步起着至关重要的作用。在这些系统中&#xff0c;图像与文本不再是孤立…

Python | Leetcode Python题解之第137题只出现一次的数字II

题目&#xff1a; 题解&#xff1a; class Solution:def singleNumber(self, nums: List[int]) -> int:a b 0for num in nums:b ~a & (b ^ num)a ~b & (a ^ num)return b

【vue实战项目】通用管理系统:图表功能

目录 前言 1.概述 2.数据概览页 2.1.柱状图 2.2.折线图 2.3.地图 前言 本文是博主前端Vue实战系列中的一篇文章&#xff0c;本系列将会带大家一起从0开始一步步完整的做完一个小项目&#xff0c;让你找到Vue实战的技巧和感觉。 专栏地址&#xff1a; https://blog.csd…

harbor1.7.1的访问报错502 bad gateway

背景&#xff1a; 在访问harbor镜像仓库时提示报错如下&#xff1a; 问题分析&#xff1a; 根据提供的报错内容来看时harbor服务的nginx组件服务异常了的&#xff0c;导致无法访问harbor服务&#xff0c;查看harbor服务结果如下&#xff1a; serviceharbor:~/harbor$ docker…

MicroPython esp32 连接wifi 配网

整体流程&#xff1a; 1&#xff09;开启STA 和 AP 模式 2&#xff09;扫描周围wifi 保存在 变量 wifi_list&#xff08;后面要用到&#xff09; 3) 尝试STA模式连接Wifi&#xff0c;并查寻状态。 4) 如果STA 无法连网&#xff0c;就用AP模式&#xff0c;创建热点。 5&a…

Vue数据动态代理机制的实现

Object.defineProperty() &#xff08;1&#xff09;这个方法是ES5新增的 &#xff08;2&#xff09;这个方法的作用是&#xff1a;给对象新增属性&#xff0c;或者设置对象原有的属性 &#xff08;3&#xff09;用法&#xff1a;Object.defineProperty(给哪个对象新增属性,‘…

【吊打面试官系列-Mysql面试题】BLOB 和 TEXT 有什么区别 ?

大家好&#xff0c;我是锋哥。今天分享关于 【BLOB 和 TEXT 有什么区别&#xff1f;】面试题&#xff0c;希望对大家有帮助&#xff1b; BLOB 和 TEXT 有什么区别 &#xff1f; BLOB 是一个二进制对象&#xff0c;可以容纳可变数量的数据。TEXT 是一个不区分大小写的 BLOB。 1…

InfiniGate自研网关实现思路七

25.网关Nginx负载模型配置 通过模拟多个HTTP服务配置到 Nginx 做负载均衡&#xff0c;以学习API网关负载的配置和使用 API 网关是用于支撑分布式 RPC 接口协议转换提供 HTTP 调用的一套服务&#xff0c;那么 API 网关系统就需要可横向扩展来满足系统的吞吐量诉求。所以这里需…

两轮自平衡小车资料(L298N 模块原理图及使用说明+c源码)

本文详细介绍了基于STM32微控制器的两轮自平衡小车的设计与实现过程。内容包括小车的硬件选型、电路设计、软件编程以及PID控制算法的应用。通过陀螺仪和加速度计获取小车的姿态信息&#xff0c;利用PID控制算法调整电机输出&#xff0c;实现小车的自主平衡。此外&#xff0c;还…

Elasticsearch之写入原理以及调优

1、ES 的写入过程 1.1 ES支持四种对文档的数据写操作 create&#xff1a;如果在PUT数据的时候当前数据已经存在&#xff0c;则数据会被覆盖&#xff0c;如果在PUT的时候加上操作类型create&#xff0c;此时如果数据已存在则会返回失败&#xff0c;因为已经强制指定了操作类型…

调查显示各公司在 IT 安全培训方面存在差距

网络安全提供商 Hornetsecurity 最近进行的一项调查显示&#xff0c;许多组织的 IT 安全培训存在严重缺陷。 这项调查是在伦敦举行的 Infosecurity Europe 2024 期间发布的&#xff0c;调查发现 26% 的组织没有为其最终用户提供任何 IT 安全培训。 这些调查结果来自世界各地的…

Nginx的https功能和防盗链

目录 一.HTTPS功能简介 二.https自签名证书 三.防盗链 一.HTTPS功能简介 Web网站的登录页面都是使用https加密传输的&#xff0c;加密数据以保障数据的安全&#xff0c;HTTPS能够加密信息&#xff0c;以免敏感信息被第三方获取&#xff0c;所以很多银行网站或电子邮箱等等安…

力扣hot100:739. 每日温度/54. 螺旋矩阵

文章目录 一、 739. 每日温度二、54. 螺旋矩阵1、模拟螺旋矩阵的路径2、按层模拟 一、 739. 每日温度 LeetCode&#xff1a;739. 每日温度 经典单调栈问题&#xff0c;求下一个更大的数。 使用单调递减栈&#xff0c;一个元素A出栈&#xff0c;当且仅当它第一次出现比它更大…

Linux常见故障处理之df命令卡住不输出

一、背景说明 朋友咨询Linux系统下输入df -h命令后没有任何输出结果&#xff0c;博主的第一反应是/根分区磁盘空间满了&#xff0c;朋友说cd等其他命令可以执行。博主又猜测可能是有人误定义了命令别名&#xff0c;进一步确认命令卡住在等待输出页面。事后博主想起来可能是共享…

【Docker系列】跨平台 Docker 镜像构建:深入理解`--platform`参数

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

【计网复习】应用层总结(不含HTTP和错题重点解析)

应用层总结&#xff08;不含HTTP和错题重点解析&#xff09; 应用层简介 应用层的主要功能常见的应用层协议小林对于应用层通常的解释 网络应用模型 客户端-服务器模型&#xff08;Client-Server Model, C/S&#xff09; 特点优点缺点应用场景 对等网络模型&#xff08;Peer-to…

中文文案写作有哪些合适的AIGC工具?

这是计育韬老师第 8 次开展面向全国高校的新媒体技术公益巡讲活动了。而在每场讲座尾声&#xff0c;互动答疑环节往往反映了高校师生当前最普遍的运营困境&#xff0c;特此计老师在现场即兴答疑之外&#xff0c;会尽量选择有较高价值的提问进行文字答疑梳理。 *本轮巡讲主题除了…

8.数砖数

上海市计算机学会竞赛平台 | YACSYACS 是由上海市计算机学会于2019年发起的活动,旨在激发青少年对学习人工智能与算法设计的热情与兴趣,提升青少年科学素养,引导青少年投身创新发现和科研实践活动。https://www.iai.sh.cn/problem/879 题目描述 给定一种 2222 规格的瓷砖,…

标准发布实施 | 《村镇污水处理一体化集成装备技术规范》

根据《中华人民共和国标准化法》以及国家标准化管理委员会、民政部联合制定的《团体标准管理规定》&#xff0c;依据全国团体标准信息平台和《中华环保联合会团体标准管理办法&#xff08;试行&#xff09;》&#xff0c;全国团体标准《村镇污水处理一体化集成装备技术指南》&a…

Scanpy(3)单细胞数据分析常规流程

单细胞数据分析常规流程 面对高效快速的要求上,使用R分析数据越来越困难,转战Python分析,我们通过scanpy官网去学习如何分析单细胞下游常规分析。 数据3k PBMC来自健康的志愿者,可从10x Genomics免费获得。在linux系统上,可以取消注释并运行以下操作来下载和解压缩数据。…