【问题标题】:Joining columns of different formats连接不同格式的列
【发布时间】:2016-10-05 16:21:00
【问题描述】:

我正在寻找一种优雅的方式来重新格式化数据以进行连接。我有两张表,它们的关键数据相同,但格式明显不同。

我正在使用 SQL Server。数据看起来像这样 表一:

74-123-58
896-777-92
4567-78

表 2:

00007400123
00089600777
00456700078

表 1 中的键分别用破折号分割成元素,有时缺少第 3 个元素(表 2 中未找到)。

表 2 始终将第一个元素的左零填充为 6 个字符,第二个元素的左零填充为 5 个字符。

我可以通过一个包含嵌入式 charindex、left、substring 和复制函数的非常长的公式来完成此操作。我想用一些简单的东西来编写它,并且对于将来尝试对我的代码进行故障排除的人来说更容易理解。

有什么好主意吗?

【问题讨论】:

  • 如果你想使用“一些简单的东西”来完成它,那么首先你必须修复你的架构并使用适当的键进行连接,这也可以利用索引。对于当前(损坏的)数据库,连接的唯一方法是放置一个表达式以从另一个获取格式。

标签: sql sql-server


【解决方案1】:

这两个看起来都像字符串,所以使用like。你需要做一些字符串处理,但我认为这行得通:

select . . .
from t1 join
     t2
     on t1.key like cast(left(t2.key, 6) + 0 as varchar(255)) + '-' +
                    cast(right(t2.key, 5) + 0 as varchar(255)) + '%';

不过,您确实应该在数据中解决这个问题。

注意:上面有一个问题,因为第二个键可能是 1,它会匹配 100。这可以通过确保后面跟着一个连字符来解决。但是,我们需要注意两部分键:

select . . .
from t1 join
     t2
     on t1.key + '-' like cast(left(t2.key, 6) + 0 as varchar(255)) + '-' +
                          cast(right(t2.key, 4) + 0 as varchar(255)) + '-%';

我强烈建议您将计算列添加到创建标准化格式的每个表中。然后,您可以在计算列上创建索引,甚至可以为此类查询获得一点性能。

【讨论】:

  • + 0 是否应该将表达式转换为整数,去除前面的零?
  • @KamilG。 . . .是的。
【解决方案2】:

根据你想去的方向,我看到两个选项:

on t2.[key] =
    right(
        '000000' +
        left(
            t1.[key],
            charindex('-', t1.[key]) - 1
        ),
        6
    ) + 
    right(
        '00000' +
        substring(t1.[key],
            charindex('-', t1.[key]) + 1,
            charindex('-', t1.[key] + '-', charindex('-', t1.[key]) + 1) -
              charindex('-', t1.[key]) - 1
        ),
        5
    )

和:

on t1.[key] + '-' like
    cast(cast(substring(t2.[key], 1, 6) as int) as varchar(6)) + '-' + 
    cast(cast(substring(t2.[key], 7, 5) as int) as varchar(5)) + '-' + '%'

如果您有一个带有format() 的SQL Server 版本,您可以使用它来代替right('000000' + X, 6) 方法。

【讨论】:

    【解决方案3】:

    这些是其他一些方法。

    SELECT *
    FROM Table1 t1
      JOIN Table2 t2 on REPLACE(t1.value1,'-','') 
      LIKE cast(left(t2.value2, 6)+ 0 as varchar(255))
           + cast(right(t2.value2, 5) + 0 as varchar(255))+'%'
    

    SELECT *
    FROM Table1 t1
      JOIN Table2 t2 on REPLACE(t1.value1,'-','') 
            LIKE REPLACE(LTRIM(REPLACE(left(t2.value2, 6), '0', ' ')),' ', '0')
                 + REPLACE(LTRIM(REPLACE(right(t2.value2, 5), '0', ' ')),' ', '0')+'%'
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-09-24
      • 2021-08-30
      • 1970-01-01
      • 2016-11-09
      • 1970-01-01
      • 2020-07-18
      • 2016-08-23
      • 2016-10-16
      相关资源
      最近更新 更多