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左连接忽略第一个字母的列的主要内容,如果未能解决你的问题,请参考以下文章