使用记录子集进行搜索的SQL

时间:2016-11-27 01:07:59

标签: sql db2 subset

有没有办法从表A中选择表B中存在相应子集的所有子集?表A中的每个子集必须至少具有表B中对应子集的所有条目。

this link中,它被称为“有剩余的分裂”但我的问题更复杂,因为我有很多关系。

表A

用户名文字|文件文字| AccessLevel int

表B

AppName文字|文件文字| AccessLevel int

示例数据

表A

User1 | aaa.txt | 1
User1 | bbb.txt | 3
User1 | ccc.txt | 1
User2 | aaa.txt | 3

表B

Appl1 | aaa.txt | 1
Appl1 | bbb.txt | 1
Appl2 | aaa.txt | 1
Appl3 | bbb.txt | 5
Appl4 | aaa.txt | 1
Appl4 | bbb.txt | 1
Appl4 | ccc.txt | 1
Appl4 | ddd.txt | 1

预期结果:

User1 | Appl1
User1 | Appl2
User2 | Appl2

User1对应用程序Appl1和Appl2具有“完全”访问权限,因为他必须访问这些应用程序使用的所有文件。他无法访问应用程序Appl3,因为访问级别不够高。他无法访问应用程序Appl4,因为他无法访问文件ddd.txt。

基本上我需要比较记录的子集并返回表B中的子集等于或大于表A中的子集的所有情况。在SQL中有什么办法吗?

任何帮助表示感谢。

2 个答案:

答案 0 :(得分:0)

一种方法是自联接,然后将匹配记录的数量与应用程序所需的数量进行比较。

假设没有重复:

select a.username, b.appname
from a join
     (select b.*, count(*) over (partition by b.appname) as cnt
      from b
     ) b
     on a.filetext = b.filetext and
        a.accesslevel >= b.accesslevel
group by a.username, b.appname, b.cnt
having count(*) = b.cnt

答案 1 :(得分:0)

SELECT distinct A1.USERNAME, B1.APPLICATION
FROM TABLEUSER A1
INNER JOIN TABLEAPPLI B1 on B1.filename=A1.filename and B1.accesslevel<=A1.accesslevel
where not exists
(
select * 
from TABLEUSER A2 INNER JOIN TABLEAPPLI B2 on B2.filename<>A2.filename or B2.accesslevel>A2.accesslevel 
where (A1.USERNAME, B1.APPLICATIONAME) = (A2.USERNAME, B2.APPLICATIONAME)
)