SQL 比较由 space 分隔的值

SQL to compare values separated by space

亲爱的,

我的 oracle table 中有如下值:

值由 space 分隔。我需要检查 value1 列中存在的所有值是否都存在于 value2 中。如果是,请将 isMatch 更新为 'Y'.

我可以通过 PLSQL 做到这一点,因为我的 table 包含 200 万条记录,这需要很多时间。

这可以通过 SQL 完成吗?

------ padaleiana 的回答更新----
请在下面找到解释计划:

我添加了 /*+ ORDERED USE_HASH(b) append */ 提示以及在 value1 和 value2 上创建索引,但成本仍然太高。

谢谢。

也许有更好和更优化的解决方案,但一个解决方案可能是下面的(假设您的 table 被称为 table1):

MERGE INTO table1 t1
USING table1 t2 ON (regexp_count(t2.value1, replace(t1.value1, ' ', '|')) =
        regexp_count(t1.value2, replace(t1.value1, ' ', '|')))
WHEN MATCHED THEN
    UPDATE SET t1.isMatch = 'Y';

MERGE command 就像 upsert。在这种情况下,您只需要使用 WHEN MATCHED THEN...,因为如果找不到匹配的行,您不想插入新值。
REGEXP_COUNT 表示某个模式在字符串中出现的次数。这里,模式是 replace(t1.value1, ' ', '|')(用 | 替换空格),字符串是 t1.value1.

这里是demo.

每个值列都可以单独拆分、排序,然后合并。在连接过程中,通过与原始 table 的每个 ID 值的最大数量的不同拾取片段进行比较,检查每个拆分片段的相等性。因此,使用以下查询:

WITH t1 AS
(
 SELECT DISTINCT ID, REGEXP_SUBSTR(value1,'[^ ]+',1,level) AS value1, level AS cnt
   FROM t -- original table
CONNECT BY level <= REGEXP_COUNT(value1,' ') + 1
    AND PRIOR SYS_GUID() IS NOT NULL
    AND PRIOR ID = ID
 ORDER BY value1
), t2 AS
(
 SELECT DISTINCT ID, REGEXP_SUBSTR(value2,'[^ ]+',1,level) AS value2, level AS cnt
   FROM t
CONNECT BY level <= REGEXP_COUNT(value2,' ') + 1
    AND PRIOR SYS_GUID() IS NOT NULL
    AND PRIOR ID = ID
 ORDER BY value2
)
SELECT DISTINCT t.*, 
       CASE WHEN SUM(CASE WHEN t1.value1 = t2.value2 THEN 1 END) OVER (PARTITION BY t.ID)
                = MAX(t1.cnt) OVER (PARTITION BY t.ID) 
            THEN
               'Y'
            ELSE
               'N'
             END AS ismatch
  FROM t 
  LEFT JOIN t1  
    ON t1.ID = t.ID     
  LEFT JOIN t2
    ON t2.ID = t1.ID   
   AND t1.value1 = t2.value2
 ORDER BY t.ID;

 

Demo