sql – 如何在正则表达式上连接表

假设我有两个表msg用于消息,mnc用于移动网络代码.
他们没有任何关系.但我想加入他们
SELECT msg.message,msg.src_addr,msg.dst_addr,mnc.name,FROM "msg"
JOIN "mnc"
ON array_to_string(regexp_matches(msg.src_addr || '+' || msg.dst_addr,'38(...)'),'') = mnc.code

查询失败并出现错误

psql:marketing.sql:28: ERROR:  argument of JOIN/ON must not return a set
LINE 12: ON array_to_string(regexp_matches(msg.src_addr || '+' || msg...

有没有办法做这样的加入?还是我走错了路?

解决方法

正如@Milen已经提到的那样,regexp_matches()可能是出于你的目的而错误功能.你想要一个简单的 regular expression match (~).实际上,LIKE operator (~~)会更快:

想象最快的LIKE

SELECT msg.message,mnc.name
FROM   mnc
JOIN   msg ON msg.src_addr ~~ ('%38' || mnc.code || '%')
           OR msg.dst_addr ~~ ('%38' || mnc.code || '%')
WHERE  length(mnc.code) = 3

此外,您只需要3个字符的mnc.code.

用regexp

您可以使用正则表达式编写相同的内容,但它肯定会更慢.这是一个接近原文的工作示例:

SELECT msg.message,mnc.name
FROM   mnc
JOIN   msg ON (msg.src_addr || '+' || msg.dst_addr) ~ (38 || mnc.code)
           AND length(mnc.code) = 3

这也要求msg.src_addr和msg.dst_addr为NOT NULL.

第二个查询演示了附加检查长度(mnc.code)= 3如何进入JOIN条件或WHERE子句.这里效果相同.

使用regexp_matches()

您可以使用regexp_matches()进行此操作:

SELECT msg.message,mnc.name
FROM   mnc
JOIN   msg ON EXISTS (
    SELECT * 
    FROM   regexp_matches(msg.src_addr ||'+'|| msg.dst_addr,'38(...)','g') x(y)
    WHERE  y[1] = mnc.code
    )

但相比之下它会很慢 – 或者我认为.

说明:
你的regexp_matches()表达式只返回第一个匹配的所有捕获的子串的数组.由于您只捕获一个子字符串(模式中的一对括号),因此您将专门获取包含一个元素的数组.

你得到的所有匹配额外的“全局”开关’g’ – 但是在多行中.所以你需要一个子选择来测试它们(或聚合).把它放在一个EXISTS – 半连接中,你得到你想要的东西.

也许你可以通过三种性能测试报告回来?
使用EXPLAIN ANALYZE.

相关文章

(一)日志传送架构 (1.1)相关服务器 主服务器 :用于生产的服务器,上面运行这生产SQL Server数据库...
(一)事故背景 最近在SQL Server 2012生产数据库上配置完事物复制(发布订阅)后,生产数据库业务出现了...
(一)测试目的 目前公司使用的SQL SERVER 2012高可用环境为主备模式,其中主库可执行读写操作,备库既...
(一)背景个人在使用sql server时,用到了sql server的发布订阅来做主从同步,类似MySQL的异步复制。在...
UNION和OR谓词 找出 product 和 product2 中售价高于 500 的商品的基本信息. select * from product wh...
datawhale组队学习task03