2016-11-09 98 views
0

您好我有一个表,其中如下面如何使用分割功能中的条件两侧在Oracle

user_country 
    ------------- 
    210|9|211 
    210|211 
    9|87 
    210|117|54 

和我有与该字符分割数据的分割功能中的值“|” 。 当用户输入像210 | 9 这样的值时,应该返回包含210和9值的列(即单独行1应该返回)。 我试图与多个存在,但无法获得实际的答案

试过至今:

SELECT 1 
    FROM TABLE(split_text_fn('210|9', '|')) a 
    WHERE EXISTS 
     (SELECT 1 
      FROM TABLE(split_text_fn('210|87', '|')) b 
     WHERE  b.COLUMN_VALUE = a.COLUMN_VALUE 
       AND EXISTS 
         (SELECT 1 
          FROM TABLE(split_text_fn('210|9', '|')) a1 
         WHERE a1.COLUMN_VALUE = b.COLUMN_VALUE)) 
+0

请发布您尝试的代码。 –

+3

你会考虑正常化你的db模型吗?同一列中的多个数据不是一种好的做法。 –

+0

另外,请不要所需结果为该数据 – Aleksej

回答

0

我不能完全肯定我理解,但是......假设你的函数将采取竖线分隔字符串并将其拆分为包含的许多标记,并假设用户输入管道分隔字符串作为绑定变量:input,并且您的基本表为table_1,并且列user_country以及其他列可能并且您希望查找所有table_1其中user_country包含:input的所有标记:

select * 
from table_1 
where not exists (select column_value from table(split_text_fn(:input, '|')) 
        minus 
        select column_value from table(split_text_fn(user_country)) 
       ) 
; 

这可能会花费大量的时间 - 必须付出的代价违反第一范式。你可以有很好的表现,或者你可以在这个非常糟糕的设计中获得数据,但不能同时拥有这两个数据

0

如果我理解正确的话,我觉得你以后是这样的:

WITH your_table AS (SELECT 1 user_id, '210|9|211' user_country FROM dual UNION ALL 
        SELECT 2 user_id, '210|211' user_country FROM dual UNION ALL 
        SELECT 3 user_id, '9|87' user_country FROM dual UNION ALL 
        SELECT 4 user_id, '210|117|54' user_country FROM dual), 
-- end of mimicking a table containing your data; you wouldn't need the above subquery 
-- as you would just select directly from your table instead 
    vals_to_check AS (SELECT regexp_substr(:p_values_to_check_for, '[^'||:p_delimiter||']+', 1, LEVEL) val, 
          COUNT(DISTINCT regexp_substr(:p_values_to_check_for, '[^'||:p_delimiter||']+', 1, LEVEL)) OVER() cnt_vals 
        FROM dual 
        CONNECT BY regexp_substr(:p_values_to_check_for, '[^'||:p_delimiter||']+', 1, LEVEL) IS NOT NULL) 
SELECT yt.user_id, 
     yt.user_country 
FROM your_table yt 
     INNER JOIN vals_to_check vtc ON :p_delimiter||yt.user_country||:p_delimiter LIKE '%'||:p_delimiter||vtc.val||:p_delimiter||'%' 
GROUP BY yt.user_id, 
     yt.user_country, 
     vtc.cnt_vals 
HAVING COUNT(*) = cnt_vals; 

结果:

-- with the bind variables set to the following: 
variable p_delimiter varchar2 
variable p_values_to_check_for varchar2 
exec :p_delimiter := '|'; :p_values_to_check_for := '210|9'; 

    USER_ID USER_COUNTRY 
---------- ------------ 
     1 210|9|211 

-- with the bind variables set to the following: 
variable p_delimiter varchar2 
variable p_values_to_check_for varchar2 
exec :p_delimiter := '|'; :p_values_to_check_for := '210|211'; 

    USER_ID USER_COUNTRY 
---------- ------------ 
     1 210|9|211 
     2 210|211 

注:我直接在sql中分割输入字符串 - 不需要单独的pl/sql函数调用。但是,您可能希望继续使用split_text_fn函数,在这种情况下,您可以跳过声明vals_to_check子查询,并在主SQL语句中使用table(split_text_fn(...))