【问题标题】:SQL: Feeding SELECT output to LIKESQL:将 SELECT 输出提供给 LIKE
【发布时间】:2012-04-06 03:56:10
【问题描述】:

问题:

select STR1 from T1 where STR2 = 'NAME1'

在上面的查询中,STR1 可以是 {ABC, ABC_1, ABC_2,..., MNO, XYZ, XYZ_1...}。

假设我有以下输出

ABC_1
MNO
XYZ

现在我想提取所有匹配 STR1 且包含 _# 之前的部分。例如,上面示例数据集的预期输出是:

ABC
ABC_1
ABC_2

MNO

XYZ
XYZ_1

请注意,每个 STR1 的 STR2 始终是唯一的。

代码方面,我想像以下这样的事情:

SELECT 
    STR1 
FROM 
    T1 
WHERE
    STR1 
LIKE '% (truncate_underscore_part(select STR1 from T1 where STR2 = 'NAME1')) %'

有什么想法吗?

第一个解决方案:

select t1.str1
  from (
  select case when instr( str1, '_' ) > 0
                then substr( str1, 1, instr( str1, '_' ) - 1 )
              else str1
         end prefix
    from t1 where str2 = 'NAME1'
) prefix_list,
  t1
  where t1.str1 like prefix || '%'

【问题讨论】:

  • 你用的是oracle还是mySql?
  • 您的第一个查询的输出示例仅显示不带下划线的项目,但我是否从您的描述中了解到第一个列表也可能包含“ABC_1”等,并且您想要在继续匹配之前剥离字符串的 _# 部分?
  • 为什么这个标签既是Oracle又是MySQL???
  • 我不太明白你的意思。如果我对您的理解正确,您有一个表格,其中包含格式为somethingsomething_n 的字段。给定什么样的输入,你想要什么样的输出?
  • @MichaelFredrickson 我正在使用 oracle。

标签: sql regex database oracle


【解决方案1】:
with prefix_list as (
  select regexp_substr( str1, '^[A-Z]*' ) prefix from t1 where str2 = 'NAME1'
)
select t1.str1 from t1 join prefix_list
        on t1.str1 = prefix_list.prefix
           or regexp_like( t1.str1, prefix_list.prefix||'_[0-9]' )

要在没有 regexp 函数的情况下执行此操作(对于较旧的 Oracle 版本),这取决于您想要验证字符串格式的程度。

select t1.str1
  from (
  select case when instr( str1, '_' ) > 0
                then substr( str1, 1, instr( str1, '_' ) - 1 )
              else str1
         end prefix
    from t1 where str2 = 'NAME1'
) prefix_list,
  t1
where t1.str1 = prefix
   or t2.str1 like prefix || '\__' escape '\'

【讨论】:

  • 对不起,我不做 TOAD。试试 SQLPlus 或 SQL Developer。
  • 不管TOAD、sqlplus都是oracle错误。我都试过了。
  • 您使用的是哪个版本的 Oracle?
  • 对于这个特定的数据库:Oracle9i Enterprise Edition Release 9.2.0.8.0。
  • 啊,我想 regexp_* 函数是在 10 中引入的。
【解决方案2】:

一种方法是使用自联接。

这是 MySQL 的一个示例:

SELECT t2.str1
FROM t1 
  INNER JOIN T1 as t2 on (t2.str1 = t1.str1 OR t2.str1 LIKE CONCAT(t1.str1,'\_%'))
WHERE t1.STR2 = 'NAME1'

这里尝试将其转换为 Oracle 语法:

SELECT t2.str1
FROM t1 
  INNER JOIN T1 as t2 on (t2.str1 = t1.str1 OR t2.str1 LIKE t1.str1 || '\_%')
WHERE t1.STR2 = 'NAME1'

【讨论】:

  • 我的回答是针对 MySQL 的,因为您的问题最初被标记为 MySQL。我会试着把它翻译成 Oracle。
  • 对不起标签。不管再次出现同样的错误('as' 上的光标)。
【解决方案3】:

在 Oracle 中,我会使用

where regexp_like(str1, '[A-Z]{3}(_[0-9]+)?')

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-01-03
    • 2021-05-19
    • 2016-05-02
    • 2015-03-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多