【问题标题】:Query matching patterns based on an offline table基于离线表查询匹配模式
【发布时间】:2013-10-20 20:55:22
【问题描述】:

我是 PostgreSQL 新手。 我目前正在开发第 3 方 PostgreSQL 数据库,并且我的 READ 权限有限,因此我无法创建临时表或创建“用户定义”变量。 此外,我发现在 Postgres 中处理正则表达式比在 MySQL 中更困难。

问题:
我有以下虚拟表:

Code   |  Name
11199  |  a
22299  |  b
33399  |  c
44499  |  a
55599  |  c

现在我有一个数字的脱机列表(无法在此数据库中创建/修改表)。 我需要选择代码以这些数字开头的名称 - 但返回代码应该是查询语句中的代码。

数字列表示例:

1
2
3
4
5

想要的查询结果:

code  |   name
1     |   a
2     |   b
3     |   c
4     |   a
5     |   c

如果我有更多的数据库权限(例如将列表插入数据库中的表,加上使用临时表+如果我可以像在 mysql 中使用正则表达式),我可以想办法完成它,但我没有知道从哪里开始使用 Postgres。帮助? :)

【问题讨论】:

  • 从您提供的链接中:“Postgres 也被接受为替代名称。” ;)
  • 您的列表中的每个号码可以有多个匹配项吗?您是否希望结果中有多行?
  • 没错。注意到“Postgre”和“Postgres”之间的区别了吗?

标签: sql postgresql pattern-matching temp-tables


【解决方案1】:

类似这样的:

-- using cte as your list of numbers
with cte as (
   select unnest(array[1, 2, 3, 4, 5]) as Number
)
select c.Number, t.name
from Table1 as t
    inner join cte as c on t.code::text like c.Number::text || '%'

sql fiddle demo

【讨论】:

  • 好心的先生,我欠你一杯啤酒! :) 谢谢,它就像一个魅力!
【解决方案2】:

重新审视你的假设。 Regular expressions are a basic, standard feature in Postgres.还有一些built-in functions using regex

不过,您在此处需要正则表达式。使用标准 SQL LIKE 运算符。一个overview over pattern-matching in Postgres in this related answer on dba.SE

您可以将列表作为数组和unnest() as demonstrated by Roman 提供,也可以使用VALUES expression 直接提供临时表。我也假设,多行可以匹配,并且您只希望列表中的每个数字有一个结果:

SELECT n.nr, array_agg(t.name) AS names
FROM  (VALUES (1), (2), (3), (4), (5)) n(nr)
JOIN   tbl t ON t.code LIKE (n.nr || '%')
GROUP  BY 1

大型列表的高级解决方案

如果您有一个(大)文件保存数字(以及必要的特权!),您可以使用更高级的技术,例如:

  • COPY 到临时表
  • pg_read_file()(特殊用途,需要超级用户权限)
  • 文件上的外部数据包装器 (file_fdw)

相关答案及详细信息:
Read data from a text file inside a trigger

blog by Depesz. 中的外部数据包装示例

【讨论】:

    猜你喜欢
    • 2013-08-19
    • 2017-02-17
    • 1970-01-01
    • 2019-03-16
    • 1970-01-01
    • 1970-01-01
    • 2019-10-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多