【问题标题】:SQL Nested ReplaceSQL 嵌套替换
【发布时间】:2012-10-26 23:27:50
【问题描述】:

我有一个复杂的嵌套替换,我用它来连接 MSSQL 中的两个表。

select * from A
  left outer join 
select * from B
on
  replace(
     replace(
        replace(
           replace(
              replace(A.Column1, '1114', ''),
             '1160', ''), 
          '1162', ''),
        '1167', ''),
      '1176', ''),
    '1177', '')  = B.Column1

我这样做的全部原因是因为 Table1 中的数据包含一些 噪音 - 像 11601162 等数字,其中 Table2 是干净的字符。

Eg. - Table 1 - 'HELLO1160WORLD'
      Table 2 - 'HELLOWORLD'

现在在我的情况下,我应该能够将它们匹配作为一个条目。

我目前的嵌套替换方法确实有效,但我不相信这是一种优雅的方法。任何帮助都感激不尽。谢谢

【问题讨论】:

  • 我希望您将SELECT * 用于说明目的,而不是作为练习。
  • 您可以发布一些示例数据,然后显示您想要的最终结果吗?
  • 当然。您需要什么帮助?
  • 是的,我实际上并没有使用 * - 只是为了让事情变得更简单。我会编辑原始问题以使其更清晰
  • 'HELLO1160WORLD' 是有效的数据吗?如果是的话,真可惜。如果没有,为什么不在前端进行消毒?

标签: sql sql-server


【解决方案1】:

也许使用函数来剥离non-numeric characters

Create Function [dbo].[RemoveNonAlphaCharacters](@Temp VarChar(1000))
Returns VarChar(1000)
AS
Begin

    While PatIndex('%[^a-z]%', @Temp) > 0
        Set @Temp = Stuff(@Temp, PatIndex('%[^a-z]%', @Temp), 1, '')

    Return @Temp
End

然后你会在你的join中引用这个函数:

select a.col1 a, b.col1 b
from tablea a
left join tableb b
  on dbo.RemoveNonAlphaCharacters(a.col1) = b.col1

SQL Fiddle with Demo

【讨论】:

  • 谢谢,这将是一个优雅的解决方案。唯一的问题是我不想删除所有非 apha 数字。抱歉不清楚。可能存在HELLO1114WORLD1HELLOWORLD1 等情况,我有一组非常具体的值(具体的交易代码)我想删除
  • @dopplesoldner 那么这两个值不匹配吗?你能发布一个更大的数据样本,然后是预期的结果吗?
  • 嗨@bluefeet 我希望将以下值视为匹配 HELLO1114WORLD1 HELLOWORLD1 M125ICKY1114MOUSE M125ICKYMOUSE RONA1160DINHO10 RONALDINHO10 目前通过使用我的嵌套替换,我正在替换某些已知的标识符 - 例如11141160 给我完全匹配。希望对您有所帮助,再次感谢!
  • @dopplesoldner 你能把这个函数应用到两列吗?类似于这个演示——sqlfiddle.com/#!3/11e59/1
  • 顺便说一句,感谢您向我展示 SQL Fiddle,我从未听说过!
【解决方案2】:

问题在于 T-SQL 不允许用名称标记表达式,因此您可以从不同的地方引用它们。不过有一种方法可以做到这一点:

select replaceN
from T
cross apply (select replace1 = replace(T.col, 'x', 'y')) r1
cross apply (select replace2 = replace(replace1, 'x', 'y')) r2
cross apply (select replace3 = replace(replace2, 'x', 'y')) r3
...

这至少摆脱了疯狂的嵌套。它对性能没有负面影响。

【讨论】:

  • 这是一个很好的解决方案......一旦我理解了它。 “replaceN”是序列中编号最高的替换,在本例中为replace3
【解决方案3】:

Bluefeet 的建议肯定会很好地使您的查询变得更简单。但是,如果您不想打扰某个函数并将所有代码保存在一个地方,请尝试此操作。在进行联接之前,您可以将表 A 转储到临时表中:

DECLARE @TmpA TABLE(
     Column1 [nvarchar] (50)),
     ...
     )

Insert into @tmpA select * from A

Update @TmpA set Column1=Replace(Replace(Replace(Column1,...)))

Select * from tmpA
  left outer join 
Select * from B
  on tmpA.Column1=B.Column1

【讨论】:

  • 但是这样,我仍然留下讨厌的嵌套循环。 (我首先要避免)
  • 正确,但它至少会将嵌套循环移出 Join 并进入它自己的部分。
猜你喜欢
  • 2019-03-08
  • 2015-02-14
  • 2018-08-16
  • 2019-01-24
  • 1970-01-01
  • 2016-07-14
  • 2015-06-11
  • 2021-07-16
  • 1970-01-01
相关资源
最近更新 更多