SQL左连接忽略第一个字母的列

Posted

技术标签:

【中文标题】SQL左连接忽略第一个字母的列【英文标题】:SQL left join on column ignoring first letter 【发布时间】:2021-05-16 09:08:42 【问题描述】:

我正在尝试使用表 a 中的“order id”和表 b 中的“order ref”来左连接 2 个表。

问题是订单将完全是数字“12345”,订单参考将在相同数字“a12345”之前有一个字母

想知道是否有办法进行连接但忽略表 b 中的字母?

欢迎任何想法

谢谢

【问题讨论】:

【参考方案1】:

当然。你在 JOIN 中看到的东西是真实的陈述;它们根本不需要与表数据有任何关系

A JOIN B ON EXTRACT(HOUR FROM NOW()) = 12

这会将 A 中的所有行与 B 中的所有行连接起来,但仅在每天一小时内(您必须在 12:00 到 12:59:59 之间运行它) - 这与表数据无关

想象一下,连接的工作类似于“A 中的每一行都与 B 中的每一行连接,然后对结果中的每一行评估真值语句。如果为假,则丢弃该行。因此 ON 1=1 是有效并包含所有行,因为它始终为真..


因此,将 A 中的所有行加入到 B 中,其中 B 是开头带有“a”的行,如下所示:

A JOIN B ON A.ID = SUBSTR(B.ID, 2, LENGTH(B.ID) - 1))

不过要小心;操作表数据会扼杀索引的使用

还可以考虑B.ID LIKE CONCAT('_', A.ID)

【讨论】:

【参考方案2】:

如果订单引用总是在订单 ID 后面有一个单字母前缀,那么只需加入前者的子字符串:

SELECT *
FROM TableA a
INNER JOIN TableB b
    ON SUBSTR(b.order_ref, 2, LENGTH(b.order_ref) - 1) = a.order_id;

如果订单 ref 可能有也可能没有那个单字母前缀,您可以尝试在任一条件下加入:

SELECT *
FROM TableA a
INNER JOIN TableB b
    ON b.order_ref = a.order_id OR
       SUBSTR(b.order_ref, 2, LENGTH(b.order_ref) - 1) = a.order_id;

【讨论】:

【参考方案3】:

考虑使用 regexp_* 函数套件来提供帮助。

例如

select * 
from A left join B 
on 
   regexp_extract(A.order_id, ‘^\D*(\d+)’, 1) =
   regexp_extract(B.order_ref, ‘^\D*(\d+)’, 1);

在这种情况下,\D* 表示出现零个或多个非数字字符,后跟一个或多个由括号捕获的数字。这让您在加入期间不忽略任何数字前缀(如果有)

【讨论】:

以上是关于SQL左连接忽略第一个字母的列的主要内容,如果未能解决你的问题,请参考以下文章

如何将一张表复制到另一张表

SQL中的左连接与右连接,内连接有啥区别

SQL左连接避免空条目

使用模糊逻辑连接两个数据集

SQL语法错误左/内/右连接

mysql左连接和右连接的区别