2016-12-04 65 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