pgsql 使用技巧

article/2025/11/6 19:18:12

1.CASCADE 级联删除,如果表或模式或数据库有序列、分区相关 依赖时,需要修改表或模式或数据库,则使用它

DROP SCHEMA viid_facestatic  CASCADE

2.pgsql隐藏字段ctid,一般用于去重

3. pg 表自连接使用场景

3.1 有一张卡口表 求距离A卡口L米的所有卡口ID

-- 查询以卡口ID为1为圆心,半径为100米 范围内的其他卡口信息
SELECT a.tollgate_name,a.longitude,a.latitude,b.tollgate_name,b.longitude,b.latitude 
FROM tollgate a JOIN tollgate b
ON a.tollgate_id <>b.tollgate_id
AND 2 * asin(sqrt(power(sin((a.latitude * pi()/180.0-b.latitude * pi()/180.0) / 2), 2) + cos(a.latitude * pi()/180.0) * cos(b.latitude * pi()/180.0) * power(sin((a.longitude * pi()/180.0 - b.longitude * pi()/180.0)/2),2)))*6378.137*1000 <= 100
WHERE a.tollgate_id=1 

3.2 使用自连接替代lead(a,1),lead(a,2),lead(a,3)......

场景:已知字段 商品名,年,月,销售额,求累计的销售额

即已知:

求:

代码:

--
SELECT*from public.sp;
--
SELECT s_id,year,a_month,a_money,array_agg(month),sum(money) from
(
select a.s_id,a.year,a.month as a_month,a.money as a_money,b.month,b.money from public.sp a 
INNER JOIN public.sp b
on a.s_id=b.s_id
where a.year=b.year and b.month<=a.month
)a GROUP BY a.s_id,a.year,a_month,a_money;

3.3 使用自连接 实现滑动窗口

已知:

求:如果某人在10s,在大于等于2个酒店被抓拍到,则认为该人短时间内在多个宾馆登记开房-判断为疑似组织卖淫人员,要求筛选出组织卖淫证据(记录)

SELECT *FROM (
--5. 关联原表 获取每个窗口的抓拍详情,如果一个人在同一个批次的同一个酒店被抓拍多次,则去重只保留该酒店第一次的抓拍记录
SELECT b.*,a.cnt,a.rn as time_batch_id,row_number()over(PARTITION by b.name,b.jdname,a.rn ORDER BY b.recordtime) min_rn  FROM (
--4. 为去重后的每人在每个窗口的结果指定一个统一的批次id
SELECT a.*,ROW_NUMBER()over(partition by null order by a.recordtime,a.name) as rn FROM (
SELECT a.* FROM (
--3. 去掉窗口子集(即一个窗口完全属于另一个窗口,则去掉该窗口)
SELECT a.* ,ROW_NUMBER()over(partition by a.name,a.real_etime ORDER BY a.real_stime) dis_rn FROM (
--2.计算各个窗口内酒店的个数,并得到每个窗口中第一条和最后一条数据的时间
WITH  a  as (
--1. 为每条记录分配一个窗口,窗口大小为10s
SELECT *,recordtime as s_time,recordtime+10 as e_time FROM (SELECT id,name,age,jdname,recordtime as rtime,EXTRACT(epoch FROM TIMESTAMPtz(recordtime)) as recordtime fromtest1)a)SELECT a.id,a.name,a.recordtime,a.rtime,
a.s_time,a.e_time,min(b.recordtime) real_stime,max(b.recordtime) real_etime,count(DISTINCT b.jdname) as cnt
FROM a INNER JOIN a as b
on  a.name=b.name  and b.s_time BETWEEN a.s_time AND a.e_time 
GROUP BY a.id,a.name,a.recordtime,a.rtime,
a.s_time,a.e_time
-- 2.1过滤出酒店个数大于指定个数的窗口
HAVING count(DISTINCT b.jdname)>=2
)a)a WHERE a.dis_rn=1)a)a
INNER JOIN (SELECT id,name,age,jdname,recordtime as rtime,EXTRACT(epoch FROM TIMESTAMPtz(recordtime)) as recordtime fromtest1) b
ON a.name=b.name  AND b.recordtime BETWEEN a.real_stime AND a.real_etime
)a WHERE a.min_rn=1
order by a.recordtime,a.name;

结果:一个批次ID对应一个滑动窗口

3. pg序列的创建场景

创建主键的自增序列:

CREATE SEQUENCE viid_facestatic.resource_id_seq INCREMENT 1 START 1 MINVALUE 1

4.pg系统表的使用场景

4.1 系统表:information_schema.tables

场景1:扫描出该数据库下的满足某种条件的一个或者多个表

例子: 假设该库下有表名为:table_201901,table_201902,table_201903.....table_2019012 的12张表,这12张表 表结构相同

需求:对table_201901到table_201907这几张表 的数据 做某个逻辑处理

实现:

select table_schema||'.'||table_name as table_name 
from information_schema.tables 
where table_type = 'BASE TABLE' 
and table_name >= 'face_archive_201901' 
and table_name <=  'face_archive_201907' ;

5.pg系统字段的使用场景(ctid去重)

6. pg json字段处理与递归查询

场景1:求所有采集设备 所属的社区 的社区名称

sql

--递归从设备找到其所属社区
-- 字段:resource 表示设备IDSELECT a.s_resource,a.e_resource,a.resource_name,a.s_entry_exit::text::INTEGERFROM(with RECURSIVE le (e_resource,resource_name,parent_resource,jsontext,s_entry_exit,s_resource,depath) as (select resource as e_resource,resource_name,parent_resource,jsontext,jsontext->'entry_exit'  as s_entry_exit,resource as s_resource,1 AS depath from viid_facestatic.resourceunion allselect e2.resource as e_resource,e2.resource_name,e2.parent_resource,e2.jsontext,e3.s_entry_exit,e3.s_resource,e3.depath+1from resource e2,le e3 where e3.parent_resource=e2.resource)select  le.e_resource,le.resource_name,le.s_entry_exit,le.jsontext,s_resource,depathfrom le WHERE le.jsontext::json->>'ctype'='社区' )a;----------------------------------------------------------------------SELECT a.s_resource,a.e_resource,a.resource_name,a.s_entry_exitFROM(with RECURSIVE le (e_resource,resource_name,parent_resource,jsontext,s_entry_exit,s_resource,depath) as (select resource as e_resource,resource_name,parent_resource,jsontext,jsontext->'entry_exit'as s_entry_exit,resource as s_resource,1 AS depath from resource WHERE resource='50011200001191000012'union allselect e2.resource as e_resource,e2.resource_name,e2.parent_resource,e2.jsontext  ,e3.s_entry_exit,e3.s_resource,e3.depath+1from resource e2,le e3 where e3.parent_resource=e2.resource)select  le.e_resource,le.resource_name,le.s_entry_exit,le.jsontext,s_resource,depathfrom le WHERE le.jsontext::json->>'ctype'='社区' )a;
----------------------------------------------------------------------
--json转text再转integer:le.s_entry_exit::text::INTEGER
--  (b.jsontext->''entry_exit'')::text::INTEGER as entry_exit
-- 查看是否转换成功:pg_typeof(le.s_entry_exit::text::INTEGER)

查询结果

7. json强制类型转换只能直接转text,再转其他类型

SELECT a.*,b.longitude,b.latitude,b.name,(b.jsontext->'entry_exit')::text::INTEGER as entry_exit FROM tablename1 a INNER JOIN viid_facestatic.device b ON
a.device_id1 = b.ape_idSELECT (value::jsonb->>'iscs_person')::jsonb->>'name' as name,jsonb_array_elements((value::jsonb->>'iscs_house')::jsonb)->>'address' as address,*  FROM "archive_info" 
where value::jsonb->>'datatype' ='iscs_person' or value::jsonb->>'datatype' ='iscs_house'

8. pg中按某一个或其中几个字段去重,只保留第一条

9.获取字段为json或者jsono类型的里面的key,value

10. 时间转换

10.1 字符串日期 与数字时间 互转

-- 无时区差(精确到秒),如果精确到毫秒 数字需要*1000
SELECT EXTRACT(epoch FROM cast('2019-08-01 00:00:02' AS TIMESTAMPTZ)),to_char(to_TIMESTAMP(1564588802),'yyyy-MM-dd HH24:MI:SS');-- 有时区差
SELECT EXTRACT(epoch FROM cast('2019-08-01 00:00:02' AS TIMESTAMP)),to_char(to_TIMESTAMP(1564617602),'yyyy-MM-dd HH24:MI:SS');-- cast()转为非整点,且+8
SELECT EXTRACT(epoch FROM cast('2019-08-01 00:00:02' AS TIMESTAMP));
-- date()转为整点的数字,且+8
-- 下面两个结果一样的
SELECT EXTRACT(epoch FROM date('2019-08-01 00:00:00'));
SELECT EXTRACT(epoch FROM date('2019-08-01 00:00:02'));
-- cast()转为非整点,且不+8
SELECT EXTRACT(epoch FROM cast('2019-08-01 00:00:02' AS TIMESTAMPTZ));

11. 通过两个点的经纬度计算两点间的距离

--发一:直接使用公式 ,计算结果单位为公里 select abs(6371.004 * acos(sin(纬度1) *sin(纬度2) * cos(经度1 - 经度2) +cos(纬度1) * cos(纬度2)) * acos(-1) / 180) as distance--法二:需要在pg中安装一个插件,然后使用以下公式SELECTST_Distance(ST_SetSRID(ST_MakePoint(a.longitude,a.latitude),4326)::geography,ST_SetSRID(ST_MakePoint(a.leadlongitude,a.leadlatitude),4326)::geography)as distance-- 发三:计算结果为单位米(推荐)
2 * asin(sqrt(power(sin((a.latitude * pi()/180.0-a.leadlatitude * pi()/180.0) / 2), 2) + cos(a.latitude * pi()/180.0) * cos(a.leadlatitude * pi()/180.0) * power(sin((a.longitude * pi()/180.0 - a.leadlongitude * pi()/180.0)/2),2)))*6378.137*1000 as distance

12.where 后用case when

SELECT id,name
FROM kx_customer
WHERE 1 = 1
AND CASE
WHEN customertype = 1 THENsaleareaid = 2
ELSEcustomercode = 'QD'
END
AND customername like '%渠道%'

13.遍历二维数组

CREATE OR REPLACE FUNCTION "dts_vehicle_resource"."traverse_2_array"("tollgateid_arr" _varchar)RETURNS "pg_catalog"."int8" AS $BODY$-- 遍历二维数组。-- 作者:余伟--sql: SELECT * FROM "dts_vehicle_resource"."test"('{{3},{4,5}}')DECLAREv_sql_seq1 text;v_sql_seq2 text;result1 record;data_num int8;tollgateids_temp  varchar;beginraise notice 'tollgateids_temp: %', array_length(tollgateid_arr,1) ;raise notice 'tollgateids_temp: %', array_length(tollgateid_arr,2) ;for i in 1 .. array_length(tollgateid_arr,1) loop tollgateids_temp:='';for k in 1 .. array_length(tollgateid_arr,2) loopIF tollgateid_arr[i][k]<>'NULL' THENtollgateids_temp = tollgateids_temp||''''||tollgateid_arr[i][k]||''',';END IF;end loop;select trim(trailing ',' from tollgateids_temp)||'' into tollgateids_temp;raise notice 'tollgateids_temp: %', tollgateids_temp;end loop;
RETURN 1; 
end;
$BODY$LANGUAGE plpgsql VOLATILECOST 100

14.WHERE NOT EXISTS


--场景: 当业务中有一些 包含规则或者剔除规则时候使用。
-- 如果有查询结果,查询结果就会全部被1替代
--当不需要知道结果是什么,只需要知道有没有结果的时候会这样用),可以提高语句的运行效率,
--在大数据量的情况下,提升效果非常明显
SELECT *FROM PUBLIC.book WHERE NOT EXISTS (
SELECT 1 FROM saler WHERE saler."saler_bookId"=book.book_id);
--等价
SELECT *FROM PUBLIC.book WHERE book_id NOT IN (
SELECT saler."saler_bookId" FROM saler )

15. pg中的 like 与 ~*

SELECT *FROM book WHERE book_name LIKE '__语文';
SELECT *FROM book WHERE book_name LIKE '%语文';
SELECT *FROM book WHERE book_name LIKE '%语文%';
SELECT *FROM book WHERE book_name LIKE '高_语_';
SELECT *FROM book WHERE book_name ~* '语文';
SELECT *FROM book WHERE book_name ~* '.*初';

16 .vertica 替代distinct on

使用distinct根据多个字段去重的同时又能选取多个字段值。法一:SELECT distinct on(book_name,recordtime) * FROM book ;法二:
SELECT * FROM (
SELECT *,row_number()over(partition by book_name,recordtime ORDER BY book_id)rn
FROM book )a WHERE a.rn=1;

17. 用sum(1)求表行数 

 


http://chatgpt.dhexx.cn/article/m82s7xy1.shtml

相关文章

pgsql

这里写目录标题 pgpool安装pgsql流复制备份与恢复客户端验证服务器设置及操作服务器配置监控数据活动 PostgreSQL是以加州大学伯克利分校计算机系开发的 POSTGRES, Version 4.2为基础的对象关系型数据库管理系统(ORDBMS)。 PostgreSQL是最初伯克利代码的一个开放源码的继承者。…

pgsql基本操作

pgsql基本操作 1. 修改postgresql.conf postgresql.conf存放位置在/etc/postgresql/9.x/main下&#xff0c;这里的x取决于你安装PostgreSQL的版本号&#xff0c;编辑或添加下面一行&#xff0c;使PostgreSQL可以接受来自任意IP的连接请求。 listen_addresses *2. 修改pg_hb…

pgsql常用sql和函数

常用pgsql -- 列出所有schema select * from information_schema.schemata; -- Schema下所有表 select * from pg_tables where schemaname query_db and tablename in(port,device,res_carry_business,hardware,shelf,device_hardware_relation); -- Schema下所有索引 select…

PGSQL大小写敏感总结

PGSQL大小写敏感总结 由于PGSQL使用会出现大小写敏感的问题&#xff0c;所以在设置字段名字的时候&#xff0c;如果字段名需要大写需要加上""号来表示&#xff0c;该字段需要大写 公司业务需要我使用PGSQL创建自增主键&#xff0c;我在使用 nextval() 绑定创建的序列…

PGSQL常用操作

0. 启动pgsl数据库 pg_ctl -D /xx/pgdata start 回到顶部 1. 查看pgsl版本 pg_ctl --version 回到顶部 1. 命令行登录数据库 1 psql -U username -d dbname -h hostip -p port 回到顶部 2. 列出所有数据库 \l 回到顶部 3. 切换数据库 1 \c dbname 回到顶部 …

PL/pgSQL

1.简介 L/pgSQL是一种用于PostgreSQL数据库系统的可载入的过程语言。 可以被用来创建函数和触发器过程对SQL语言增加控制结构可以执行复杂计算继承所有用户定义类型、函数和操作符可以被定义为受服务器信任便于使用 [1]使用PL/pgSQL的优点 SQL 是一种查询语言&#xff0c;可…

Windows 10 安装配置连接PostgreSQL教程

Windows 10 安装配置连接PostgreSQL教程 1.1 PostgreSQL 下载1.2 配置环境变量1.3 PostgreSQL 初始化1.4 创建postgres用户1.5 启动postgresql1.6 客户端连接测试1.6.1 SQL Shell (psql)命令行连接测试1.6.2 客户端 pdAdmin 4 连接测试1.6.3 客户端Navicat Permium 连接测试 1.…

Spring原理-IOC控制反转

spring相关文章 Spring原理-IOC控制反转 Spring框架七大核心模块 Spring Beans原理–bean生命周期 一、Spring概述 1、 定义 Spring是一个轻量级Java开发框架&#xff0c;最早有Rod Johnson创建&#xff0c;目的是为了解决企业级应用开发复杂性。它是一个分层的JavaSE/Java…

依赖倒置和控制反转

依赖倒置 定义 依赖反转原则&#xff08;Dependency inversion principle&#xff0c;DIP&#xff09;是指一种特定的解耦形式&#xff0c;使得高层次的类不依赖于低层次的类的实现细节&#xff0c;依赖关系被颠倒&#xff08;反转&#xff09;&#xff0c;从而使得低层次类依…

Inversion of Control (IOC)控制反转 有什么好处

要了解控制反转( Inversion of Control ), 我觉得有必要先了解软件设计的一个重要思想&#xff1a;依赖倒置原则&#xff08;Dependency Inversion Principle &#xff09;。 什么是依赖倒置原则&#xff1f;假设我们设计一辆汽车&#xff1a;先设计轮子&#xff0c;然后根据…

Spring学习:IOC控制反转

一、Spring概述&#xff1a; Spring是一个开源框架&#xff0c;其存在的根本使命就是简化JAVA开发。为了降低JAVA开发的复杂性&#xff0c;Spring采取了以下四种关键策略&#xff1a; 基于POJO的最轻量级和最小侵入性编程&#xff1b;通过依赖注入和面向接口实现松耦合&#x…

控制反转(IOC)简介

IOC是Inversion of Control的缩写&#xff0c;多数书籍翻译成“控制反转”&#xff0c;还有些书籍翻译成为“控制反向”或者“控制倒置”。 1996年&#xff0c;Michael Mattson在一篇有关探讨面向对象框架的文章中&#xff0c;首先提出了IOC 这个概念。对于面向对象设计及编程…

IoC 控制反转理解

控制反转——Inversion of Control&#xff0c;缩写为IoC &#xff0c;是一个重要的面向对象编程的法则&#xff0c;说到底它是一种设计思想&#xff0c;其可以降低程序中的耦合度&#xff0c;在以前&#xff0c;我们通过new进行创建对象&#xff0c;这是程序主动去创建依赖对象…

IOC控制反转理解

1. IOC基础 IOC&#xff1a;全称Inversion Of Control&#xff0c;中文翻译是控制反转的意思。初学Spring绕不过去的一个弯&#xff0c;需要好好理解IOC的思想。网上看了很多博客&#xff0c;也看了很多网课&#xff0c;但是还是云里云雾。终于看到一个容易理解的例子&#xf…

C# IoC控制反转学习笔记

一、什么是IOC IoC-Invertion of Control&#xff0c;即控制反转&#xff0c;是一种程序设计思想。 先初步了解几个概念&#xff1a; 依赖&#xff08;Dependency&#xff09;&#xff1a;就是有联系&#xff0c;表示一个类依赖于另一个类。 依赖倒置原则&#xff08;DIP&a…

spring -- 控制反转IOC

1.IOC的理论背景 在面向对象设计的软件系统中&#xff0c;它的底层都是由N个对象构成的&#xff0c;各个对象之间通过相互合作&#xff0c;最终实现系统地业务逻辑。 图1 软件系统中耦合的对象 齿轮组中齿轮之间的啮合关系,与软件系统中对象之间的耦合关系非常相似。对象之间…

Java:控制反转

Java中自带的函数或对象都是编写软件的时候写的&#xff0c;当它需要调用你自己编写的数据的时候&#xff0c;它如何又不知道你定义的类&#xff08;对象&#xff09;是什么&#xff0c;里面有什么成员&#xff0c;它无法调用你的代码&#xff0c;这个时候就需要用到控制反转了…

IoC控制反转

IoC控制反转 一、IoC概念和原理1. 什么是IoC2. IoC底层原理 二、IoC过程1. xml配置文件&#xff0c;配置创建的对象2. 有UserService和UserDao类&#xff0c;创建工厂类 三、IoC接口1. IoC思想基于IoC容器完成&#xff0c;IoC容器底层就是Bean工厂2. Spring提供实现IoC容器的两…

IOC 控制反转

文章目录 一.IOC概念二. IOC的体现三.ioc的技术实现三.基于XML的DI1.引用类型属性自动注入 四.包含关系的配置文件五.基于注解的DI五.简单类型的属性赋值1.vaule(简单类型的属性赋值&#xff09;2.自动注入 一.IOC概念 IOC&#xff1a;控制反转&#xff0c;是一个理论&#xf…

浅谈控制反转(IoC)

Inversion of Control 什么是控制反转&#xff1f; 程序的流程控制权相对于传统的面向过程编程而言发生了反转。下面是维基百科的描述 In software engineering, inversion of control (IoC) is a programming principle. IoC inverts the flow of control as compared to tr…