0

我在表中有一个包含波浪号分隔数据的列。

我想触发一个 SINGLE sql 查询(出于性能原因),它应该返回表中的所有记录,对于这些记录,此波浪号分隔数据中的至少一个标记不在有效值的预定义列表中。

我曾在各种论坛中寻找解决方案,其中大多数人说有一个用户定义的拆分函数来拆分记录或使用一些正则表达式,但这不适用于单个查询。

有人可以帮我吗?

4

1 回答 1

3

您可以使用正则表达式在单个 SQL 语句中解析数据。然后,您可以应用您想要的任何过滤器来查找不在预定义列表中的值集

SQL> ed
Wrote file afiedt.buf

  1  with test as
  2    (select 'ABC~DEF~GHI~JKL~MNO' str from dual)
  3  select regexp_substr (str, '[^~]+', 1, rownum) split
  4    from test
  5* connect by level <= length (regexp_replace (str, '[^~]+'))  + 1
SQL> /

SPLIT
----------------------------------------------------------------------------
ABC
DEF
GHI
JKL
MNO

你也可以做这样的事情

SQL> ed
Wrote file afiedt.buf

  1  with test as
  2    (select 1 id, 'ABC~DEF~GHI~JKL~MNO' str from dual union all
  3     select 2, 'XY~PDQ~435' from dual union all
  4     select 3, 'This~is~a~test' from dual)
  5  select id, regexp_substr (str, '[^~]+', 1, e.lvl) split
  6    from test,
  7         (select level lvl
  8            from dual
  9         connect by level <= (select max(regexp_count(str,'~')) + 1
 10                                from test)) e
 11*  where regexp_substr (str, '[^~]+', 1, e.lvl) is not null
SQL> /

        ID SPLIT
---------- --------------------
         1 ABC
         2 XY
         3 This
         1 DEF
         2 PDQ
         3 is
         1 GHI
         2 435
         3 a
         1 JKL
         3 test
         1 MNO

12 rows selected.

当然,这不会特别有效——您将不得不对表进行全面扫描,因为您将无法有效地索引各种子字符串。还有其他生成行的方法——Rob van Wijk在他的博客中有一篇文章比较了各种基于间隔的行生成技术的性能。

修复数据模型通常会好得多。在列中存储分隔数据违反了基本的规范化原则。如果您将数据存储在单独的列中(可能在与现有表具有一对多关系的单独表中),您可以索引数据,并且可以创建映射到预定义的有效列表的外键约束值,以便您可以首先防止插入无效数据(或至少防止将来添加新的无效行)。

于 2012-06-26T19:50:15.807 回答