在两列中的一个字符上联接

Join on one character out of two columns

提问人:JohnT 提问时间:10/11/2023 更新时间:10/11/2023 访问量:42

问:

我有以下两个表,我想根据每个表中每列内容的一部分进行内部连接,这两个表中的内容等于一个值。 在下面的示例中,我想在两个表中连接两个表,其中我连接了“组”列中包含“B”的所有行。

------------------------
First table TABLE1: 
Group       Name
------------------------
A,B,C,D,E   CustomerNameA... 
G,E,D,L,P   CustomerNameB...
A,B,C,D,E   CustomerNameC... 
...

------------------------
Second table TABLE2
Group   Device
------------------------
A,Z     CustomerDeviceA...
A,B,C   CustomerDeviceB...
Z,P,O   CustomerDeviceC...
B,C,E   CustomerDeviceD...
...

我不能使用

...
JOIN TABLE2
On TABLE1.Group like Concat('%', TABLE2.Group,'%')

因为“B”在两个 TABLE1 中的位置。组和 TABLE2.组不稳定。“B”位于两列中的某个位置。 我试过了:

...
JOIN TABLE2
On (TABLE1.Group like '%B%' AND TABLE2.Group like '%B%')

但它会按预期返回不同的结果。

SQL MySQL 联接

评论

0赞 Ryan Wilson 10/11/2023
你打算如何加入?如果得到的结果集包括包含“B”的所有记录,则可以将每个集中的每条记录与另一组中的每条记录联接起来。您在寻找什么样的预期结果?您确定不希望根据哪些结果集包含字母“B”来生成结果集吗?UNION
2赞 NickW 10/11/2023
如果您对数据进行了规范化,那么您就不会遇到这些类型的问题 - 这就是为什么以规范化形式拥有数据被认为是良好做法的原因
0赞 dougp 10/11/2023
请发布预期的输出。

答:

0赞 dougp 10/11/2023 #1

您的问题缺乏足够的细节,无法提供单一、准确的答案。

下面的查询是针对 SQL Server 编写的,但这些概念应该很容易转换为 MySQL。

我们将从输入开始:

with TABLE1 as (
  select *
  from (
    values
      ('A,B,C,D,E', 'CustomerNameA')
    , ('G,E,D,L,P', 'CustomerNameB')
    , ('A,B,C,D,E', 'CustomerNameC')
  ) q ([Group], [Name])
), 
TABLE2 as (
  select *
  from (
    values 
      ('A,Z'  , 'CustomerDeviceA')
    , ('A,B,C', 'CustomerDeviceB')
    , ('Z,P,O', 'CustomerDeviceC')
    , ('B,C,E', 'CustomerDeviceD')
  ) q ([Group], [Device])
)

这将为您提供所有数据,并用“包含 B”和“不包含 B”连接:

T1 as (
  select *
  , case when [Group] like '%B%' then 1 else 0 end as joincol
  from TABLE1
),
T2 AS (
  select *
  , case when [Group] like '%B%' then 1 else 0 end as joincol
  from TABLE2
)

select *
from T1
  inner join T2 ON T2.joincol = T1.joincol

这将为您提供所有数据,这些数据显示由“包含 B”连接的行和其他不匹配的行。

,
T1 as (
  select *
  , case when [Group] like '%B%' then 1 end as joincol
  from TABLE1
),
T2 AS (
  select *
  , case when [Group] like '%B%' then 1 end as joincol
  from TABLE2
)

select *
from T1
  full outer join T2 ON T2.joincol = T1.joincol

这将只给你由“contains B”连接的行。

,
T1 as (
  select *
  , case when [Group] like '%B%' then 1 end as joincol
  from TABLE1
),
T2 AS (
  select *
  , case when [Group] like '%B%' then 1 end as joincol
  from TABLE2
)

select *
from T1
  inner join T2 ON T2.joincol = T1.joincol

https://dbfiddle.uk/gANc7olQ

0赞 Lajos Arpad 10/11/2023 #2

“我不能用”

JOIN TABLE2
On TABLE1.Group like Concat('%', TABLE2.Group,'%')

事实上。但这就是任务:

在下面的示例中,我想在两个表中连接两个表,其中我连接了“组”列中包含“B”的所有行。

因此,您对所有具有 .因此,您可以使用:B

JOIN TABLE2
ON CONCAT(',', TABLE1.Group, ',') LIKE '%B%' AND
   CONCAT(',', TABLE2.Group, ',') LIKE '%B%'

诀窍是我在 的值前面附加一个逗号,以便对于任何此类字段或其他任何字段的结果,如果此结果中存在,那么它将位于两个逗号之间,这也处理了可变子字符串长度的问题。GroupCONCATB

评论

0赞 JohnT 10/22/2023
就我而言,这很有效。谢谢。
0赞 Lajos Arpad 10/22/2023
@JohnT很乐意提供帮助。您可以考虑将此答案标记为正确答案,以便其他有类似问题的访问者知道问题已解决。