PostgreSQL LATERAL 的工作原理

2024-05-29 19:52

本文主要是介绍PostgreSQL LATERAL 的工作原理,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

LATERAL 的工作原理

  1. 外部查询生成一行结果:LATERAL 子查询会对每一行外部查询结果进行评估。
  2. LATERAL 子查询执行:对于每一行,LATERAL 子查询会使用该行的列值来执行自己的查询。
  3. 结果合并:子查询的结果与外部查询的行合并,形成最终的结果集。

以下是一个简单的例子来说明 LATERAL 的工作原理:

示例表和数据

假设我们有一个名为 employees 的表:

CREATE TABLE employees (id SERIAL PRIMARY KEY,name TEXT,tasks JSONB
);INSERT INTO employees (name, tasks) VALUES
('Alice', '[{"task": "task1"}, {"task": "task2"}]'),
('Bob', '[{"task": "task3"}, {"task": "task4"}]');

使用 LATERAL 的查询示例

我们想要展开每个员工的任务,并显示员工的名字和每个任务的名字。

SELECTe.name,t.task
FROMemployees e,LATERAL jsonb_array_elements(e.tasks) AS t(task);

查询解释

  1. 外部查询生成每一行结果

    • 第一行:('Alice', '[{"task": "task1"}, {"task": "task2"}]')
    • 第二行:('Bob', '[{"task": "task3"}, {"task": "task4"}]')
  2. LATERAL 子查询执行

    • 对于第一行,jsonb_array_elements('[{"task": "task1"}, {"task": "task2"}]') 展开成两行:
      • {"task": "task1"}
      • {"task": "task2"}
    • 对于第二行,jsonb_array_elements('[{"task": "task3"}, {"task": "task4"}]') 展开成两行:
      • {"task": "task3"}
      • {"task": "task4"}
  3. 结果合并

    • 第一行展开结果合并:
      • ('Alice', 'task1')
      • ('Alice', 'task2')
    • 第二行展开结果合并:
      • ('Bob', 'task3')
      • ('Bob', 'task4')

结果集

 name  | task
-------|-------Alice | task1Alice | task2Bob   | task3Bob   | task4

使用 LATERAL 和 WHERE 子句

假设我们只想筛选出特定的任务,可以在 LATERAL 子查询之后使用 WHERE 子句。

例如,筛选出任务为 task1task3 的记录:

SELECTe.name,t.task
FROMemployees e,LATERAL jsonb_array_elements(e.tasks) AS t(task)
WHEREt.task->>'task' IN ('task1', 'task3');

结果集

 name  | task
-------|-------Alice | task1Bob   | task3

总结

  • LATERAL 的作用:LATERAL 允许子查询访问外部查询的列,且会对外部查询的每一行进行评估。
  • 子查询与外部查询的关系:子查询可以使用外部查询中的列值来生成结果,并将其合并到最终的结果集中。
  • 临时结果集:LATERAL 子查询的结果会与外部查询的每一行合并,从而形成最终的结果集。

通过使用 LATERAL,我们能够在子查询中引用外部查询的列值,并根据这些列值进行进一步的数据处理和筛选。

是的,你可以使用相同的方法来处理具有多个字段的 JSON 数组。假设每个 JSON 对象都有两个字段 `task``priority`,你可以像这样修改查询来处理它:```sql
SELECTe.name,t.task,t.priority
FROMemployees e,LATERAL (SELECT (elem->>'task') AS task,(elem->>'priority') AS priorityFROM jsonb_array_elements(e.tasks) AS elem) AS t
WHEREt.task IN ('task1', 'task3');

在这个查询中,jsonb_array_elements(e.tasks) 将每个 JSON 对象展开成一行,并在子查询中使用 ->> 运算符来提取每个对象的 taskpriority 字段。然后,通过别名 t 引用这些字段。

这样,你就可以处理具有多个字段的 JSON 数组了。

在这个查询中,`LATERAL jsonb_array_elements(e.tasks) AS t(task)` 这一部分是一个 LATERAL JOIN 语句,用于将 JSON 数组 `e.tasks` 中的每个元素展开成一行。让我们来解释一下其中的各个部分:- `LATERAL`: 这是一个关键字,它告诉数据库引擎在执行查询时按顺序处理 FROM 子句中的表达式,确保对每一行计算一次。在这里,它确保对 `jsonb_array_elements(e.tasks)` 返回的每个元素都进行处理。- `jsonb_array_elements(e.tasks)`: 这是一个 JSON 函数,它将 JSON 数组 `e.tasks` 中的每个元素作为一个行返回。例如,如果 `e.tasks` 是 `["task1", "task2", "task3"]`,那么这个函数将返回三行,每行一个任务。- `AS t(task)`: 这部分给返回的行定义了一个别名 `t`,并指定了一个列别名 `task`。在查询的后续部分,你可以使用 `t.task` 来引用 `jsonb_array_elements(e.tasks)` 返回的每一行中的 `task` 列。所以,整个 LATERAL JOIN 的作用是将 JSON 数组 `e.tasks` 中的每个元素拆分成一行,并将每个元素赋值给名为 `t` 的临时表,该表只有一个名为 `task` 的列。**可以选择第几个对象**
```sql
SELECTe.name,t.task,t.priority
FROMemployees e,LATERAL (SELECT (elem->>'task') AS task,(elem->>'priority') AS priority,ROW_NUMBER() OVER () AS rnFROM jsonb_array_elements(e.tasks) AS elem) AS tleft join 
WHERE
t.rn = 1;

这篇关于PostgreSQL LATERAL 的工作原理的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1014488

相关文章

深入探索协同过滤:从原理到推荐模块案例

文章目录 前言一、协同过滤1. 基于用户的协同过滤(UserCF)2. 基于物品的协同过滤(ItemCF)3. 相似度计算方法 二、相似度计算方法1. 欧氏距离2. 皮尔逊相关系数3. 杰卡德相似系数4. 余弦相似度 三、推荐模块案例1.基于文章的协同过滤推荐功能2.基于用户的协同过滤推荐功能 前言     在信息过载的时代,推荐系统成为连接用户与内容的桥梁。本文聚焦于

hdu4407(容斥原理)

题意:给一串数字1,2,......n,两个操作:1、修改第k个数字,2、查询区间[l,r]中与n互质的数之和。 解题思路:咱一看,像线段树,但是如果用线段树做,那么每个区间一定要记录所有的素因子,这样会超内存。然后我就做不来了。后来看了题解,原来是用容斥原理来做的。还记得这道题目吗?求区间[1,r]中与p互质的数的个数,如果不会的话就先去做那题吧。现在这题是求区间[l,r]中与n互质的数的和

hdu4407容斥原理

题意: 有一个元素为 1~n 的数列{An},有2种操作(1000次): 1、求某段区间 [a,b] 中与 p 互质的数的和。 2、将数列中某个位置元素的值改变。 import java.io.BufferedInputStream;import java.io.BufferedReader;import java.io.IOException;import java.io.Inpu

hdu4059容斥原理

求1-n中与n互质的数的4次方之和 import java.io.BufferedInputStream;import java.io.BufferedReader;import java.io.IOException;import java.io.InputStream;import java.io.InputStreamReader;import java.io.PrintWrit

工作常用指令与快捷键

Git提交代码 git fetch  git add .  git commit -m “desc”  git pull  git push Git查看当前分支 git symbolic-ref --short -q HEAD Git创建新的分支并切换 git checkout -b XXXXXXXXXXXXXX git push origin XXXXXXXXXXXXXX

嵌入式方向的毕业生,找工作很迷茫

一个应届硕士生的问题: 虽然我明白想成为技术大牛需要日积月累的磨练,但我总感觉自己学习方法或者哪些方面有问题,时间一天天过去,自己也每天不停学习,但总感觉自己没有想象中那样进步,总感觉找不到一个很清晰的学习规划……眼看 9 月份就要参加秋招了,我想毕业了去大城市磨练几年,涨涨见识,拓开眼界多学点东西。但是感觉自己的实力还是很不够,内心慌得不行,总怕浪费了这人生唯一的校招机会,当然我也明白,毕业

PostgreSQL核心功能特性与使用领域及场景分析

PostgreSQL有什么优点? 开源和免费 PostgreSQL是一个开源的数据库管理系统,可以免费使用和修改。这降低了企业的成本,并为开发者提供了一个活跃的社区和丰富的资源。 高度兼容 PostgreSQL支持多种操作系统(如Linux、Windows、macOS等)和编程语言(如C、C++、Java、Python、Ruby等),并提供了多种接口(如JDBC、ODBC、ADO.NET等

寻迹模块TCRT5000的应用原理和功能实现(基于STM32)

目录 概述 1 认识TCRT5000 1.1 模块介绍 1.2 电气特性 2 系统应用 2.1 系统架构 2.2 STM32Cube创建工程 3 功能实现 3.1 代码实现 3.2 源代码文件 4 功能测试 4.1 检测黑线状态 4.2 未检测黑线状态 概述 本文主要介绍TCRT5000模块的使用原理,包括该模块的硬件实现方式,电路实现原理,还使用STM32类

husky 工具配置代码检查工作流:提交代码至仓库前做代码检查

提示:这篇博客以我前两篇博客作为先修知识,请大家先去看看我前两篇博客 博客指路:前端 ESlint 代码规范及修复代码规范错误-CSDN博客前端 Vue3 项目开发—— ESLint & prettier 配置代码风格-CSDN博客 husky 工具配置代码检查工作流的作用 在工作中,我们经常需要将写好的代码提交至代码仓库 但是由于程序员疏忽而将不规范的代码提交至仓库,显然是不合理的 所

TL-Tomcat中长连接的底层源码原理实现

长连接:浏览器告诉tomcat不要将请求关掉。  如果不是长连接,tomcat响应后会告诉浏览器把这个连接关掉。    tomcat中有一个缓冲区  如果发送大批量数据后 又不处理  那么会堆积缓冲区 后面的请求会越来越慢。