首页 > 解决方案 > 在 DB 中查找特定集合

问题描述

所以我的表如下

cgid cid vid
--------------------
CG1   C1  V1
CG1   C2  V1
CG2   C1  V1
CG2   C2  V2
CG3   C1  V1
CG4   C2  V1

等等

我的java代码中会有这样的东西

[{cid=C1,vid=V1},{cid=C2,vid=V1}]

我需要找出在java中代表这个集合的特定CGID。

现在我能做的是获取所有 CGID 并与所有数据一一进行比较,但随着表大小的增长,这已成为一个问题。有没有其他(简单的)方法可以做到这一点。

任何推荐的查询以在单个查询中获取 cgid,并传递来自 java 代码的所有输入。

标签: javasqloracle

解决方案


这是解决您问题的技巧。

with我在子句中包含了测试数据。在现实生活中,您将拥有一个实际的表格,以及提供输入的某种方式。在这里,我提供“表”作为with子句中的视图,以及您必须与之比较的“目标集”作为另一个视图,由您显示的确切格式的字符串组成。

第一步是将输入字符串打散,使“目标集”能够以与输入表相同的格式呈现。这是在norm_target(标准化目标)视图计算中完成的。如果您的目标集以某种不同的格式给出,您将需要以某种方式以与norm_target.

然后,对于每个集合 - 包括目标 - 我创建一个对所有元素进行编码的单个字符串 - 每个标记终止于#(假设此字符没有出现在您的cidvid值中的任何位置;对于更强大的解决方案,您可以用一些控件替换它字符,例如 ASCII 字符集中的“记录分隔符”或“系统铃声”)。在每种情况下,单个字符串编码都按cid, vid.

两个集合具有相同的单字符串编码当且仅当集合具有相同的对。一对中的任何一个值(或两者)都可以null- 连接#到所有内容导致null被视为正确的空字符串,而不是nullOracle 传统的泛型。此外,如果存在重复,则两组中每个不同对的重复数必须完全匹配。

与需要某种集合或直接比较 JSON 字符串(在较新版本的 Oracle 中)等的“正确”解决方案相比,这可能会更快。这是一个 hack:一个应该 100% 正确的解决方案,只是不是解决问题的标准方法;但这提供了“标准方式”所没有的一些好处。

with
  my_table (cgid, cid, vid) as (
    select 'CG1', 'C1', 'V1' from dual union all
    select 'CG1', 'C2', 'V1' from dual union all
    select 'CG2', 'C1', 'V1' from dual union all
    select 'CG2', 'C2', 'V2' from dual union all
    select 'CG3', 'C1', 'V1' from dual union all
    select 'CG4', 'C2', 'V1' from dual
  )
, target (i_set) as (
    select '[{cid=C1,vid=V1},{cid=C2,vid=V1}]'
    from   dual
  )
, norm_target (cid, vid) as (
    select  regexp_substr(i_set, '\{cid=([^,]*)', 1, level, null, 1) as cid,
            regexp_substr(i_set, ',vid=([^}]*)' , 1, level, null, 1) as vid
    from    target
    connect by level <= regexp_count(i_set, '\{')
  )
select cgid
from   my_table
group  by cgid
having listagg(cid || '#' || vid || '#') within group (order by cid, vid) =
       (
         select listagg(cid || '#' || vid || '#') 
                  within group (order by cid, vid)
         from   norm_target
       )
;

CGID
--------
CG1

推荐阅读