Postgresql CTE 表达式

前言 本文介绍如何使用 CTE 表达式来简化 PostgreSQL 中的一些复杂查询。那 CTE 表达式是什么呢? CTE 介绍 在 PostgreSql 中 WITH 提供了一种方式来书写在一个大型查询中使用的辅助语句。这些语句通常被称为公共表表达式或CTE(Common Table Expressions),它们可以被看成是定义只在一个查询中存在的临时表。在WITH子句中的每一个辅助语句可以是一个SELECT、INSERT、UPDATE或DELETE,并且WITH子句本身也可以被附加到一个主语句,主语句也可以是SELECT、INSERT、UPDATE或DELETE。在 PostgreSQL 中,WITH 子句提供了一种编写辅助语句的方法,以便在复杂的查询中使用。 使用 该如何创建 CTE 呢, 创建 CTE 的语句如下: WITH cte_name AS ( SELECT column1, column2, ... FROM table_name WHERE condition ... ) SELECT * FROM cte_name; 在日常查询中 CTE 用于哪些场景呢: 递归查询:CTE 表达式常用于执行递归查询。通过在 CTE 表达式中引用自身,可以简洁地实现递归操作。 复杂查询:CTE 表达式可以用于构建复杂的查询,将查询逻辑分解为更易于理解和维护的部分。每个 CTE 子查询块可以负责不同的逻辑操作,最终组合成一个完整的查询。 数据转换和重组:CTE 表达式可以用于对数据进行转换和重组。通过在不同的 CTE 子查询块中选择、过滤和连接数据,可以生成新的结果集。 递归查询 WITH 表达式如何实现递归查询呢,可以通过添加 RECURSIVE修饰符来实现。下面是一个示例: WITH RECURSIVE t(n) AS ( VALUES (1) UNION ALL SELECT n+1 FROM t WHERE n < 100 ) SELECT sum(n) FROM t; 这个例子是对1到100之间数求和。 ...

十一月 19, 2023 · overstarry

PostgreSQL怎么解决division by zero问题

问题 最近在使用 sql进行数值计算时,发现sql语句运行报错,报错信息如下:division by zero,综合分析sql语句得出是在进行除法运算时,除数为0导致的。 解决 接下来我来介绍几种解决这种问题的方法: NULLIF 和 COALESCE 函数 我们可以使用 NULLIF 函数检查变量是否是0值,如果是0则为null。使用COALESCE函数检查分子和分母是否有NULL值,然后返回默认值。 例子: SELECT COALESCE(dividend / NULLIF(divisor, 0), default_value) FROM xx CASE表达式 我们可以使用 case when 来检查除数是否为0,如果是0则使用默认值。 例子: SELECT COALESCE(dividend / NULLIF(divisor, 0), default_value) FROM xx 最终我采用了第一种方法,顺利的解决了问题,还需要多说的是在 postgresql sql 语句使用过程中,要注意所使用函数需要的参数的类型,遇到需要转换参数类型的情况,可以使用case函数进行类型转换。 小结 本文讲述了我遇到的 PostgreSQL 进行数值计算时遇到的 division by zero 问题的情况及解决方法。 参考 https://www.postgresql.org/docs/current/functions-conditional.html#FUNCTIONS-NULLIF https://www.postgresql.org/docs/current/sql-expressions.html#SYNTAX-EXPRESS-EVAL https://pganalyze.com/docs/log-insights/app-errors/U128 https://stackoverflow.com/questions/17681375/avoid-division-by-zero-in-postgresql

七月 1, 2023 · overstarry

Postgresql的json类型

最近工作需要使用 sql 语句进行 Postgresql json 类型字段的查询,本文特此记录下一些常用的函数。 Postgresql json 类型简介 postgresql支持两种json数据类型:json和jsonb,而两者唯一的区别在于效率,json是对输入的完整拷贝,使用时再去解析,所以它会保留输入的空格,重复键以及顺序等。而jsonb是解析输入后保存的二进制,它在解析时会删除不必要的空格和重复的键,顺序和输入可能也不相同。使用时不用再次解析。两者对重复键的处理都是保留最后一个键值对。效率的差别:json类型存储快,使用慢,jsonb类型存储稍慢,使用较快。 json 类型操作符 我们先介绍 json 和 jsonb 的一些常用通用操作符: 操作符 右操作数类型 描述 示例 结果 -> int 获取JSON数组元素(索引从0开始) select ‘[{“a”:“foo”},{“b”:“bar”},{“c”:“baz”}]’::json->2; {“c”:“baz”} -> text 通过键获取值 select ‘{“a”: {“b”:“foo”}}’::json->‘a’; {“b”:“foo”} -» int 获取JSON数组元素为 text select ‘[1,2,3]’::json-»2; 3 -» text 通过键获取值为text select ‘{“a”:1,“b”:2}’::json-»‘b’; 2 jsonb 独有的操作符 操作符 右操作数类型 描述 示例 结果 @> jsonb 左侧json最上层的值是否包含右边json对象 select ‘{“a”:{“b”:2}}’::jsonb @> ‘{“b”:2}’::jsonb;select ‘{“a”:1, “b”:2}’::jsonb @> ‘{“b”:2}’::jsonb; ft <@ jsonb 左侧json对象是否包含于右侧json最上层的值内 select ‘{“b”:2}’::jsonb <@ ‘{“a”:1, “b”:2}’::jsonb; t ? text text是否作为左侧Json对象最上层的键 select ‘{“a”:1, “b”:2}’::jsonb ? ‘b’; t ?| text[] text[]中的任一元素是否作为左侧Json对象最上层的键 select ‘{“a”:1, “b”:2, “c”:3}’::jsonb ?| array[‘b’, ‘c’]; t ?& text[] text[]中的所有元素是否作为左侧Json对象最上层的键 select ‘[“a”, “b”]’::jsonb ?& array[‘a’, ‘b’]; t || jsonb 连接两个json对象,组成一个新的json对象 select ‘[“a”, “b”]’::jsonb || ‘[“c”, “d”]’::jsonb; [“a”, “b”, “c”, “d”] - text 删除左侧json对象中键为text的键值对 select ‘{“a”: “b”}’::jsonb - ‘a’; {} - integer 删除数组指定索引处的元素,如果索引值为负数,则从右边计算索引值。如果最上层容器内不是数组,则抛出错误。 select ‘[“a”, “b”]’::jsonb - 1; [“a”] 创建json类型 那我们该如何创建json类型呢,下面介绍一些常见的函数 ...

十二月 24, 2022 · overstarry

使用 APISIX 代理 PostgreSQL 数据库

本文我来讲解如何使用 APISIX 来代理 PostgreSQL 数据库服务。 初试 最开始我以为很简单,我采用了直接在 APISIX DashBoard 上配置了一条路由,配置好后,连接发现无法成功连接,提示连接失败。 经过仔细的思考,发现 PostgreSQL 是使用 TCP 协议的数据库,不能通过简单的 route 进行配置,必须使用 stream-proxy 进行代理,接下来我们来看看怎么样来进行配置。 stream-proxy TCP 是许多流行应用程序和服务的协议,例如 LDAP、MySQL 和 RTMP。UDP(用户数据报协议)是许多流行的非事务性应用程序的协议,例如 DNS、系统日志和 RADIUS。 APISIX 可以动态负载平衡 TCP/UDP 代理。在 Nginx 的世界里,我们把 TCP/UDP proxy 称为 stream proxy,APISIX 就遵循了这个说法。 启用 stream-proxy 要开启 APISIX 流代理需要在 APISIX 配置中开启, APISIX 默认是关闭的。 apisix: stream_proxy: # TCP/UDP proxy tcp: # TCP proxy address list - 9100 - "127.0.0.1:9101" udp: # UDP proxy address list - 9200 - "127.0.0.1:9211" 如果apisix.enable_admin为 true,则 HTTP 和流代理都启用了上述配置。 ...

十二月 17, 2022 · overstarry

DataX数据同步中遇到的问题

最近在使用 DataX 进行 PostgreSQL 和 PostgreSQL 之间的数据同步,在数据同步过程中, 遇到了一个问题,在本文简单记录下问题和相应的解决方案。 问题 在一次数据同步中,DataX执行失败,错误信息如下: 具体错误信息为:com.alibaba.datax.common.exception.DataXException: Code:[DBUtilErrorCode-12], Description:[不支持的数据库类型. 请注意查看 DataX 已经支持的数据库类型以及数据库版本.]. - 您的配 置文件中的列配置信息有误. 因为DataX 不支持数据库读取这种字段类型. 字段名:[country], 字段名称:[1111], 字段Java类型:[java.lang.String]. 请尝试使用数据库函数将其转换datax支持的类型 我的配置如下: { "job": { "setting": { "speed": { "channel": 3 }, "errorLimit": { "record": 0, "percentage": 0.02 } }, "content": [ { "reader": { "name": "postgresqlreader", "parameter": { "username": "xasdas", "password": "xxx", "column": [ "id", "country" ], "connection": [ { "table": [ "xx" ], "jdbcUrl": [ "jdbc:postgresql://xxx:5432/xxxx" ] } ] } }, "writer": { "name": "postgresqlwriter", "parameter": { "username": "xxxx", "password": "x", "column": [ "id", "country" ], "preSql": [ ], "postSql": [ ], "connection": [ { "jdbcUrl": "jdbc:postgresql://xxx:5432/xxxx", "table": [ "xx" ] } ] } } } ] } } 通过检查数据库字段,发现 country 字段是 jsonb 类型,DataX不支持此类型,DataX 的支持列表: ...

十二月 7, 2022 · overstarry