连接来自两个不同表的两个列,其中两个列都有部分相似的数据

时间:2018-07-18 19:50:15

标签: sql sql-server

我有两个表,[A]和[B]。我想将表[A]的[城市]列和表[B]的[知名城市]列中的两个表连接起来。

所以表[A]中的[城市]列看起来像这样。

+---------------+
|     City      |
+---------------+
| Orlando       |
| New York      |
| Los Angeles   |
+---------------+

,表[B]中的[知名城市]列如下。

+----------------------------+
|    [Cities renown for]     |
+----------------------------+
| New York_Status of Liberty |
| Orlando_Disney World       |
| Los Angeles_Hollywood      |
+----------------------------+

我的表各有大约一万行,我想根据奥兰多= Orlando_Disney World这样的城市名称来匹配列

所以我这样写了我的查询。

Select a.[City]
from [A] as a
    inner join [B] as b
        on a.[City] = b.[Cities renown for]   
where a.[City] = b.[Cities renown for]   

我知道我在最后两行做错了,但是真的不知道如何解决

3 个答案:

答案 0 :(得分:2)

如果这是您可以控制的数据库,则建议您更改结构。如果表A只是城市列表,则城市名称应为主键。然后,表2应该有一个City列,它是TableA.City列的外键。如果表B用于存储某城市闻名的事物(并且每个城市可以因多项事物而闻名),则每个“知名度项目”都将有单独的一行(不确定这是否可行)。这样,您的查询就会简单得多。

话虽如此,如果您无法更改数据库的结构,则可以使用简单的LIKE运算符:

select TableA.City
from TableA
    inner join TableB on
        TableB.[Cities renown for] like TableA.City + '%'

正如@scsimon所指出的,您在这里不需要WHERE。同样,这种方法将能够使用索引的[Cities renown for]列。

答案 1 :(得分:1)

where子句在这里是多余的,因此您可以删除它,因为您正在使用inner join

由于Cities renown for不完全匹配,因此您需要从该列中获取城市 part

类似

Select a.[City]
from [A] as a
    inner join [B] as b on
    a.[City] = left(b.[Cities renown for]  ,charindex('_',b.[Cities renown for]  ) - 1)

这会使b.[Cities renown for]上的索引无法使用。这也基于示例数据,其中逻辑似乎为City_Renowned for,表示城市后跟下划线。在上面的代码中,我们使用charindex查找下划线的位置,并将所有内容都放在下划线的left上。

或者,正如Tab Alleman所指出的,LIKE可能会或可能不会提高性能。 Here's an article on that。:

Select a.[City]
from [A] as a
    inner join [B] as b on
    b.[Cities renown for] like a.[City] + '%'

答案 2 :(得分:0)

使用CHARINDEX查找“ _”可能会起作用。

通过CTE进行设置以阐明要点。

;WITH A (City) AS (
    SELECT * FROM (
        VALUES
            ('Orlando'), 
            ('New York'), 
            ('Los Angeles')
    ) AS A (Column1)
),
B ([Cities renown for]) AS (
    SELECT * FROM (
        VALUES
            ('New York_Status of Liberty'), 
            ('Orlando_Disney World'), 
            ('Los Angeles_Hollywood')
    ) AS A (Column1)
)

SELECT * 
FROM A 
INNER JOIN B ON A.City = LEFT(B.[Cities renown for], CHARINDEX('_', B.[Cities renown for])-1)