在 DB2 sql 中获取最接近的匹配值

Posted

技术标签:

【中文标题】在 DB2 sql 中获取最接近的匹配值【英文标题】:To get the nearest matching value in DB2 sql 【发布时间】:2016-03-28 11:43:42 【问题描述】:

我有一个包含以下值的表

   ACCNO                  TEXT
   -------------     ----------------
   8611004050001     internal payment
   861100405000X     external payment
   8611XXXXXXXXX     other payments

假设如果 accono 是 8611004050002 那么我必须 pic 外部付款。 如果 accno 是 8611211216223 那么我必须得到其他付款。

我需要得到最接近的匹配值是单个 sql 我用 case 语句尝试过它不起作用。实现这一目标的有效方法是什么。

请帮帮我

【问题讨论】:

...您的表的设计意味着一个多部分键,这将违反推荐的最佳实践。至少,它还要求您知道密钥的结构很重要,这将是一个相关的问题。根据您未来的需求,可能需要更改设计。 这是要求,我不能改变设计..这个表就像一个控制表,基于这一行(accno)他们想选择一些值..我没有在这里给出完整的表结构 我可以在程序中实现这一点(使用循环和多个 sql 语句),但如果我能够在单个查询中做到这一点,它将提高性能.. 通常在一个语句中做事效率更高。不幸的是,由于数据的结构,几乎所有内容都可能为此生成表扫描 - 您尝试查询的内容不利于索引。如果您有正确设计的表格,这将更容易和更快。哦,我假设传递像8724114159901 这样的帐户应该不会导致您的示例行被选中。另外,这些组的静态性如何?它总是前 4 个字符,除了最后一个字符之外的所有字符吗?还是每次都变? 您的帐号字符串中是否有非数字字符值? 【参考方案1】:

嗯,一种方法使用巨大的case 语句。像这样的:

select t.*
from t
order by (case when accno = <accno> then 99
               when left(accno, 15) = left(<accno>, 15) then 15
               when left(accno, 14) = left(<accno>, 14) then 14
               when left(accno, 13) = left(<accno>, 13) then 13
               when left(accno, 12) = left(<accno>, 12) then 12
               when left(accno, 11) = left(<accno>, 11) then 11
               when left(accno, 10) = left(<accno>, 10) then 10
               when left(accno, 9) = left(<accno>, 9) then 9
               when left(accno, 8) = left(<accno>, 8) then 8
               when left(accno, 7) = left(<accno>, 7) then 7
               when left(accno, 6) = left(<accno>, 6) then 6
               when left(accno, 5) = left(<accno>, 5) then 5
               when left(accno, 4) = left(<accno>, 4) then 4
               when left(accno, 3) = left(<accno>, 3) then 3
               when left(accno, 2) = left(<accno>, 2) then 2
               when left(accno, 1) = left(<accno>, 1) then 1
               else 0
          end) desc
fetch first 1 row only;

【讨论】:

:winces: ...哎哟。但是,它(可能)会产生错误的结果:87325XXXX 可能不应该被视为824119000 的帐户。 我尝试过类似的。但它提供了不止一行....获取前 1 行可以提供单行,但它逐行检查..假设表有 100 行,那么这个查询将检查每行 12 次。 我想要类似的东西,如果它匹配,那么查询应该停止..假设如果它找到完整的 accno 那么它应该停在那里,否则它应该匹配 11 个字符,否则 10 个字符。 . 我的查询是 SELECT ACCNO,TEXT FROM @tbl WHERE(当 ACCNO = '8611004050001' 然后是 '8611004050001' 否则当 ACCNO = '861100405000X' 然后是 '861100405000XXX' ELSE '8611XXX = accno WITH UR;-- @DhanyaKUMAR.S - 哦,这个查询将检索它找到的第一个匹配项(尽管我听说优化器有时会弄乱它)。它可能不会总是检索到正确的匹配。它有可能非常缓慢;取决于优化器是否足够聪明,可以部分读取accno 的索引条目。

以上是关于在 DB2 sql 中获取最接近的匹配值的主要内容,如果未能解决你的问题,请参考以下文章

在sql server中查找最接近的匹配行

SQL中最接近的部分字符串匹配

基于 SQL 查询中最接近的文本匹配连接表?

获取最接近的字符串匹配

MySQL在最接近的匹配值上加入两个表

匹配 Redshift SQL 中最近的时间戳