2016-11-09 107 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(...))