【问题标题】:How to use Search multiple LIKE for IN condition in DB2如何在 DB2 中使用 Search multiple LIKE for IN 条件
【发布时间】:2015-03-02 22:47:21
【问题描述】:
  SELECT *
  FROM XYZ
  WHERE column1 IN (X1,Y1,Z1);

我想在这个选择查询中使用 LIKE;如何用 IN 编写 LIKE 语句,类似于以下查询:

  SELECT * 
  FROM XYZ 
  WHERE column1 LIKE IN  ($P{COLUMN});

另一个例子:-

select * from (select REPLACE(REFEV_VEH_TYPE, ' ', '') || 替换(REFEV_CATEGORY,'','')||替换(REFEV_USAGE,'','')|| REPLACE(REFEV_BODY_CODE, ' ', '') 作为 UC 从 TREF_ENF_VEHICLE_TYPE ) aa where aa.UC LIKE ('%06TBISUM%')

UC
------
06TBISUM

select * from (select REPLACE(REFEV_VEH_TYPE, ' ', '') || 替换(REFEV_CATEGORY,'','')||替换(REFEV_USAGE,'','')|| REPLACE(REFEV_BODY_CODE, ' ', '') 作为 UC 从 TREF_ENF_VEHICLE_TYPE ) aa where aa.UC LIKE ('%B')

 UC
----------
06TGISJB
06TGITJB

select * from (select REPLACE(REFEV_VEH_TYPE, ' ', '') || 替换(REFEV_CATEGORY,'','')||替换(REFEV_USAGE,'','')|| REPLACE(REFEV_BODY_CODE, ' ', '') 作为 UC 从 TREF_ENF_VEHICLE_TYPE ) aa where aa.UC LIKE ('%BAS')

UC
----------
06BCIBAS
05BCABAS
05BCBBAS

我想知道的结果是:

从 ( 选择替换(REFEV_VEH_TYPE,'','')||替换(REFEV_CATEGORY,'','')||替换(REFEV_USAGE,'','')|| REPLACE(REFEV_BODY_CODE, ' ', '') 作为 UC 来自 TREF_ENF_VEHICLE_TYPE ) aa 其中 aa.UC IN LIKE ('%06TBISUM%', '%B','%BAS')。

UC
------
06TBISUM
06TGISJB
06TGITJB
06BCIBAS
05BCABAS
05BCBBAS

我使用的参数是$P{COLUMN}。 我想使用 IN LIKE($P{COLUMN}) 通过 $P{COLUMN} 参数搜索多个。有人知道吗?

【问题讨论】:

  • 如果特定行包含多个搜索词(例如'X1' 'Y1'),您希望发生什么?
  • 我想知道的结果是当我输入多个 LIKE IN($P{'%06TBISUM%', '%B','%BAS'})。所以我想要结果显示在上面的 3 LIKE 之后。
  • ...您可能想使用TRIM(...) 而不是REPLACE(...) - 您正试图摆脱前导/尾随空格,对吗?此外,如果可能的话,对源列运行 LIKEs 可能会更快(不过,您仍然无法为其使用索引)。
  • 好的。但是在 DB2 中,我不能使用 trim()。但我现在的问题是如何使用 IN 条件获得多个 LIKE 结果?你能检查我的 sql 吗?出了什么问题?。
  • 您的第一个问题是您试图将单个变量用作数组,而 DB2 并不真正支持该数组。它认为您要查找单个字符串值,包括逗号,当然没有匹配项。如果您split it to a table,那会更好(然后可以像我在回答中那样使用它)。有一些方法可以在普通递归 CTE 中进行拆分(我已经做到了),但我不太记得我是如何做到的。

标签: sql select db2 sql-like in-operator


【解决方案1】:

在 DB2 中不能将单个变量用作数组,但可以split it with a recursive CTE

这是一个不需要定义函数的版本:

WITH Split AS (SELECT '' AS value, txt, LOCATE(',', txt) AS nxt
               FROM (VALUES($P{COLUMN})) t(txt)
               UNION ALL
               SELECT DECODE(nxt, 0, txt, SUBSTR(txt, 1, nxt - 1)),
                      DECODE(nxt, 0, '', SUBSTR(txt, nxt + 1)),
                      DECODE(txt, '', 0, LOCATE(',', txt, nxt + 1))
               FROM Split
               WHERE LENGTH(txt) > 0), 

     SearchData AS (SELECT value
                    FROM Split
                    WHERE value <> '')

SELECT uc
FROM (SELECT REPLACE(refev_veh_type, ' ', '') 
              || REPLACE(refev_category, ' ', '') 
              || REPLACE(refev_usage, ' ', '') 
              || REPLACE(refev_body_code, ' ', '') AS uc
      FROM TRef_ENF_Vehicle_Type ) T
JOIN SearchData
  ON T.uc LIKE SearchData.value

(未测试,因为我手边没有 DB2 实例)

$P{COLUMN} 假定包含以下字符串:'%06TBISUM%,%B,%BAS'

【讨论】:

  • 我已经在我的 DB2 中尝试了 sql,但它得到了错误。你能再次更正你的 sql 吗?错误更多的是 VALUES($P{COLUMN})。我已经输入了您的值 '%06TBISUM%,%B,%BAS' 但结果仍然错误。所以我不知道结果如何。你能制作虚拟 sql 以便我理解你在 DB2 中的 sql
  • 我不知道您所说的“虚拟”是什么意思(如果您指的是小提琴,它不支持 DB2 - 我可能已经针对 PostgreSQL 或 Oracle 对其进行了测试)。我不知道你怎么称呼它,这可能是问题的一部分。你不能只说“有错误”,什么错误?
  • 我得到的消息错误是“DB2 SQL 错误:SQLCODE=-104, SQLSTATE=42601, SQLERRMC='%06TBISUM%,%B,%BAS';;, DRIVER= 3.57.82 错误代码:-104"
  • -104 似乎在抱怨您替换变量的方式。我假设您使用的是准备好的语句,除了关闭 SQL 注入点之外,这将使它成为非问题。从外观上看,您直接输入了值,而没有将其指定为字符串(也就是说,您没有输入 ' - 撇号)。 DB2 看着它,然后“嗯?”。
【解决方案2】:

LIKE 操作在功能上等同于多个 OR 操作。 所以..

  SELECT *
  FROM XYZ
  WHERE ( column1 like 'X1' OR column1 like 'X2' OR column1 like 'X3' )

【讨论】:

    【解决方案3】:

    试试

    其中 REGEXP_LIKE(aa.UC,'.+[06TBISUM.*|B|BAS].+')

    将 + 替换为 *(如果我将 * 放入它会转换为斜体)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-04-06
      • 2019-12-17
      • 2022-12-28
      • 2022-01-22
      • 2022-12-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多