Oracle SQL:使用 WHERE LIKE 但针对特定的整个单词 / REGEXP_LIKE

Oracle SQL: Using WHERE LIKE but for specific whole words / REGEXP_LIKE

我有 table 的发票,其中成本标识符以特定方式保存,并不总是标准的,如下所示:

ID | SYMBOL | COST_IDS
---+--------+-------------------
 1 | FV01   | '1076219, 1081419'
 2 | FV02   | '107621,123421'
 3 | FV03   | '111521; 107621'

我想查找特定费用标识符的发票。

成本的结构是(4 或更多位数)+(2年位数)

在测试用例中:107621,所需的输出将是 ID:2 and 3

SELECT * FROM INVOICES WHERE COST_IDS like '%107621%' 是错误的做法。

我发现我需要使用 REGEXP_LIKE 并且我正在努力解决它。我知道我需要准确地找到整个世界,但不一定要从头开始。

谁能帮帮我?

编辑:这似乎在大多数情况下都有效,但在字符串结尾处失败:

SELECT * 
FROM INVOICES 
WHERE REGEXP_LIKE(COST_IDS, '[^|\s|,|;]107621[$|\s|,|;]')

还有没有办法标记'non-digit'字符而不是专门写\s|,|;

为什么 $ 不起作用?

您可以使用\D来匹配一个非数字:

SELECT *
FROM   INVOICES
WHERE  REGEXP_LIKE(COST_IDS, '(^|\D)107621(\D|$)')

其中,对于示例数据:

CREATE TABLE invoices (ID, SYMBOL, COST_IDS) AS
SELECT 1, 'FV01', '1076219, 1081419' FROM DUAL UNION ALL
SELECT 2, 'FV02', '107621,123421' FROM DUAL UNION ALL
SELECT 3, 'FV03', '111521; 107621' FROM DUAL;

输出:

ID SYMBOL COST_IDS
2 FV02 107621,123421
3 FV03 111521; 107621

db<>fiddle here


您的正则表达式不能正常工作:

  • [^|\s|,|;] 匹配 而不是 |\s| 的单个字符] 或 ,|;
  • [$|\s|,|;] 匹配 $|\s| 或 [=18] 中的单个字符=] 或 |;

如果要匹配字符串开头或白色 space 字符或逗号或分号,则需要正则表达式 (^|\s|[,;]).

同样,如果你想匹配字符串结尾或白色 space 字符或逗号或分号,那么你需要正则表达式 ($|\s|[,;]).

您可以使用以下 SQL Select 语句,考虑到 cost_ids 有两个单独的部分,或者假设每个 cost_ids 值甚至只有一种类型的分隔符如果有更多部分

WITH inv AS
(
 SELECT id, REGEXP_SUBSTR(cost_ids,'[[:punct:]]+') AS symbol2, cost_ids
   FROM invoices
)
 SELECT DISTINCT id
   FROM inv   
  WHERE REGEXP_SUBSTR(cost_ids,'[^'''||symbol2||''' ]+',1,level) = '107621' 
CONNECT BY level <= REGEXP_COUNT(cost_ids,symbol2) + 1 
    AND PRIOR SYS_GUID() IS NOT NULL
    AND PRIOR id = id

其中分隔符最初通过使用 [[:punct:]] posix 的名称 symbol2 确定,用于提取标点符号。

Demo