2016-12-04 67 views
0

我有一個表(ResponseData)與列RESPONSE_ID,RESPONSEDATA,KEY1,KEY2,KEY3,KEY4,VALUE1,VALUE2,VALUE3,VALUE4 用戶可以插入數據任何以下類別。更快的搜索查詢與動態哪裏列oracle db

  • 1, 「我的回答一個」, 「姓名」,NULL,NULL,NULL, 「蘋果」,NULL,NULL,NULL
  • 2, 「我的回答兩個」, 「姓名」,「年齡」,NULL,NULL, 「蘋果」, 「22」,NULL,NULL

在不同的頁面後來當Responsedata與NAME =用戶請求 「蘋果」,年齡= 「32」 應該返回記錄1,因爲它具有匹配的屬性名稱 如果name =「Apple」age =「22」的用戶請求應返回記錄1和2,因爲它與記錄1按名稱匹配,記錄2按名稱和年齡匹配。

我們如何在這種情況下形成搜索查詢。 我試圖通過utl_match.jaro_winkler_similarity如下 utl_match.jaro_winkler_similarity(上(VALUE1 | VALUE3 | VALUE4),(USERINPUTREQUEST)),通過獲取所有現有記錄中的最高匹配記錄,但它在給出更多的查詢時給出延遲響應在桌上的數字記錄。 讚賞您的輸入。

+2

你可以將當前表分成兩個 - 包含前兩列的父表和包含鍵值對的子表?它可以簡化查詢(不需要猜測4對列中的哪一列保存數據)。 –

回答

0
declare 
    cursor c(k1 varchar2, 
      k2 varchar2, 
      k3 varchar2, 
      k4 varchar2, 
      v1 varchar2, 
      v2 varchar2, 
      v3 varchar2, 
      v4 varchar2) 
    is(select * 
     from (select ResponseData.*, 
        case 
         when (k1 = key1 and v1 <> value1) 
          or (k1 = key2 and v1 <> value2) 
          or (k1 = key3 and v1 <> value3) 
          or (k1 = key4 and v1 <> value4) 
          or (k2 = key1 and v2 <> value1) 
          or (k2 = key2 and v2 <> value2) 
          or (k2 = key3 and v2 <> value3) 
          or (k2 = key4 and v2 <> value4) 
          or (k3 = key1 and v3 <> value1) 
          or (k3 = key2 and v3 <> value2) 
          or (k3 = key3 and v3 <> value3) 
          or (k3 = key4 and v3 <> value4) 
          or (k4 = key1 and v4 <> value1) 
          or (k4 = key2 and v4 <> value2) 
          or (k4 = key3 and v4 <> value3) 
          or (k4 = key4 and v4 <> value4) 
         then 'not match' 
         else 'match' 
        end ok 
       from ResponseData) 
     where ok = 'match' 
      or ok = 'not match'); -- debug mode 
begin 
    for r in c('name', null, null, 'age', 'Apple', null, null, '22') loop 
    dbms_output.put_line(r.id||': ('||r.key1||'=>'||r.value1||'), ('||r.key2||'=>'||r.value2||'), (' 
            ||r.key3||'=>'||r.value3||'), ('||r.key4||'=>'||r.value4||') - '||r.ok); 
    end loop; 
end; 
+0

這聽起來不錯,但是如果用戶輸入key =「name」,value =「Orange」和key =「age」,value =「22」,這將返回2個記錄。 – snofty

+0

@snofty爲什麼這應該返回這兩個記錄?請求的姓名= Orange和年齡= 22與您的示例的記錄1沒有任何共同之處。我的解決方案依賴於用戶知道存儲請求的鍵值對的列數的假設。如果這是錯誤的假設,您應該搜索每個列對,查找用戶請求的每個鍵值對(16個謂詞而不是4個)。或者更好考慮使用[EAV]的Mick助記符建議(https://en.wikipedia.org/wiki/Entity%E2%80%93attribute%E2%80%93value_model) –

+0

不是紀錄,它的第2條記錄......是的用戶不知道列的數量.. – snofty