【问题标题】:SQL - Join two tables on column with similar valuesSQL - 在具有相似值的列上连接两个表
【发布时间】:2014-06-10 03:25:09
【问题描述】:

我正在尝试加入两个地址表,但遇到了麻烦,因为当街道为数字时,它们在街道名称上并不相似。例如。当第一个表街道名称等于“2nd”时,第二个表街道名称等于“2”。因此,街道尽头的标签从第二个表中排除。这些表有超过十万行。如有必要,我可以将标签添加到街道的尽头,但我也想不出任何好的方法来做到这一点。

到目前为止,这是我的代码:

select * from address a
inner join mai_address ma on ma.hse_nbr=a.number and a.street=ma.street

由于这个问题,查询不包括任何带有数字的街道。

感谢您的帮助。

【问题讨论】:

  • 您使用的是哪个数据库?另外,您能提供一些示例数据吗?
  • 删除比较中的所有非数字字符?
  • 我使用的是 ms sql server
  • 是的,使用函数删除所有非数字字符可能是要走的路。

标签: sql sql-server


【解决方案1】:

要能够将这种逻辑添加到数据库中的唯一方法是创建一个函数来删除不需要的文本。但是,将两个表连接到一个包含在函数中的字段上会非常低效。

更好的解决方案是创建函数,但使用它来更新两个表中的新字段并加入该表。这可以在触发器上完成

即:

create trigger dbo.address_update
on dbo.address
after insert, update
as
begin
  update address a
  set    processed_street = ProcessStreet(street)
  join   inserted i
  on     i.unique_field = a.unique_field;
end;

【讨论】:

  • 我想加入表的主要原因是在其中一个表上创建一个新列,其中一个列来自另一个表。这个查询只会被使用一次,因此效率应该不是问题。如果我多次执行这个查询,这肯定是有道理的,所以我给你一个向上的箭头。感谢您的洞察力。
【解决方案2】:

选择 *

  from address 

      inner join mai_address on dbo.f1(mai_address.hse_nbr) = address.street

并且函数 f1(@str) 应该返回“@str”参数的左侧数字(直到到达非数字或字符串结尾)。像这样的:

创建函数 dbo.f1(@str Varchar(10)) 将 varchar(10) 返回为

  Begin 
  define @str2 varchar(10)
  define @i int
  set @str2 = ''
    set @i = 1
    while ((@i <= len(@str)) and (substring(@str, @i, @i) between '0' and '9'))
        begin
        @str2 = concat(@str2, substring(@str, @i, @i))
        set @i = @i + 1
        end
    return @str2
end

【讨论】:

  • 我使用了一个函数来消除任何包含数字的值中的文本,并使用这个函数加入表格。这个答案中的功能究竟是做什么的?仅供参考...请参阅下面的答案。
  • f1() 在这个解决方案中提取并返回可能后跟一个或多个字符的数字。
  • 就可以了。谢谢!
【解决方案3】:

这就是我所做的。

CREATE Function [fnRemoveNonNumericCharacters](@strText VARCHAR(1000))
RETURNS VARCHAR(1000)
AS
 BEGIN
  WHILE PATINDEX('%[^0-9]%', @strText) > 0
 BEGIN
    SET @strText = STUFF(@strText, PATINDEX('%[^0-9]%', @strText), 1, '')
 END
    RETURN @strText
 END

然后加入我是这样做的:

select * from address a
inner join mai_address ma on ma.hse_nbr=a.number and (a.street=ma.street OR dbo.fnRemoveNonNumericCharacters(ma.street)=a.street)
and (ma.unit_nbr=a.apt OR (ma.unit_nbr IS NULL AND a.apt IS NULL))
order by a.number

我使用该函数来修改列值,使其不包含文本。我还使用 or 加入不包含数字的街道名称。

感谢您的好主意!

【讨论】:

  • 您可能希望将此标记为答案,以便其他人找到它。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-05-01
  • 1970-01-01
  • 1970-01-01
  • 2011-09-20
  • 2012-06-02
相关资源
最近更新 更多