如何在sql中使用类似的连接?

时间:2009-09-06 17:16:47

标签: mysql sql join sql-like

我有2个表,比如表A和表B,我想要执行连接,但是匹配条件必须是来自A'的列就像'来自B的列意味着任何事物可以在之前或之后出现B中的一栏:

例如:如果A中的列是'foo'。如果B中的列是:'fooblah','somethingfooblah'或者只是'foo',则连接将匹配。我知道如何在标准的语句中使用通配符,但在进行连接时很困惑。这有意义吗?感谢。

5 个答案:

答案 0 :(得分:72)

使用INSTR

SELECT *
  FROM TABLE a
  JOIN TABLE b ON INSTR(b.column, a.column) > 0

使用LIKE:

SELECT *
  FROM TABLE a
  JOIN TABLE b ON b.column LIKE '%'+ a.column +'%'

使用LIKE,使用CONCAT:

SELECT *
  FROM TABLE a
  JOIN TABLE b ON b.column LIKE CONCAT('%', a.column ,'%')

请注意,在所有选项中,您可能希望在比较之前将列值驱动为大写,以确保您在不考虑区分大小写的情况下获得匹配:

SELECT *
  FROM (SELECT UPPER(a.column) 'ua'
         TABLE a) a
  JOIN (SELECT UPPER(b.column) 'ub'
         TABLE b) b ON INSTR(b.ub, a.ua) > 0

效率最高将最终取决于EXPLAIN plan输出。

JOIN子句与编写WHERE子句相同。 JOIN语法也称为ANSI JOIN,因为它们是标准化的。非ANSI JOIN看起来像:

SELECT *
  FROM TABLE a,
       TABLE b
 WHERE INSTR(b.column, a.column) > 0

我不打算使用非ANSI LEFT JOIN示例。 ANSI JOIN语法的好处是它将连接表的内容与WHERE子句中实际发生的内容分开。

答案 1 :(得分:19)

在MySQL中你可以尝试:

SELECT * FROM A INNER JOIN B ON B.MYCOL LIKE CONCAT('%', A.MYCOL, '%');

当然,这将是一个非常低效的查询,因为它会进行全表扫描。

更新:这是一个证据


create table A (MYCOL varchar(255));
create table B (MYCOL varchar(255));
insert into A (MYCOL) values ('foo'), ('bar'), ('baz');
insert into B (MYCOL) values ('fooblah'), ('somethingfooblah'), ('foo');
insert into B (MYCOL) values ('barblah'), ('somethingbarblah'), ('bar');
SELECT * FROM A INNER JOIN B ON B.MYCOL LIKE CONCAT('%', A.MYCOL, '%');
+-------+------------------+
| MYCOL | MYCOL            |
+-------+------------------+
| foo   | fooblah          |
| foo   | somethingfooblah |
| foo   | foo              |
| bar   | barblah          |
| bar   | somethingbarblah |
| bar   | bar              |
+-------+------------------+
6 rows in set (0.38 sec)

答案 2 :(得分:5)

如果这是您经常需要做的事情......那么您可能希望对表A和B之间的关系进行非规范化。

例如,在插入到表B时,您可以将零个或多个条目写入基于部分映射将B映射到A的juncion表。同样,对任一表的更改都可以更新此关联。

这完全取决于表A和B的修改频率。如果它们是相当静态的,那么在INSERT上点击就不那么痛苦了,然后重复点击SELECT。

答案 3 :(得分:2)

在连接中使用条件标准肯定与Where子句不同。表之间的基数可以在Joins和Where子句之间产生差异。

例如,在外部联接中使用L​​ike条件将保留连接中列出的第一个表中的所有记录。在Where子句中使用相同的条件将隐式地将连接更改为内连接。记录必须通常出现在两个表中,以完成Where子句中的条件比较。

我通常使用之前答案之一中给出的风格。

tbl_A as ta
    LEFT OUTER JOIN tbl_B AS tb
            ON ta.[Desc] LIKE '%' + tb.[Desc] + '%'

这样我可以控制连接类型。

答案 4 :(得分:0)

在使用我们的服务器LIKE或INSTR(或T-SQL中的CHARINDEX)编写查询时,花费的时间太长,因此我们在以下结构中使用LEFT:

select *
from little
left join big
on left( big.key, len(little.key) ) = little.key

我了解到,查询可能只对不同的 end 起作用,这与其他带有'%'+ b +'%'的建议不同,但是如果只需要b +'%就足够了,而且速度要快得多'。

另一种优化速度(而不是内存)的方法是在“ little”中创建一个列“ len(little.key)”作为“ lenkey”,然后在上面的查询中创建一个用户。