在多对多关系中查找未链接的数据

时间:2013-04-30 03:28:41

标签: sql

我有三张这样的表:

Person table: primary - PersonKey
PersonFieldValue table: contains a PersonKey and a PersonFieldKey
PersonField table: primary - PersonFieldKey. 

它还包含一个Description字段和两个名为IsRequired和IsLateRequirement

的位字段

我一直在拉我的头发想出一个查询,它会给我一个人员列表,这些人在PersonFieldValue表中没有记录,匹配​​PersonField表中的记录,其中两个位字段之一为真以及缺少的字段的描述。所以,鉴于这些数据:

PersonKey
    1
    2

PersonField

PersonFieldKey    Description     IsRequired     IsLateRequirement
    1             Thing1              1                 0
    2             Thing2              0                 1
    3             Thing3              1                 0
    4             Thing4              0                 0

PersonFieldValue

PersonKey         PersonFieldKey
    1                   3
    1                   4
    2                   1
    2                   2

我应该得到这些数据:

PersonKey         MissingFieldDescription
    1             Thing1
    1             Thing2
    2             Thing3

请注意,只检查将IsRequired或IsLateRequirement设置为1的PersonField记录,以查看它们是否缺失。

那么,我该怎么做?

2 个答案:

答案 0 :(得分:2)

SELECT p.PersonKey, pf.Description as 'MissingFieldDescription' 
 FROM Person p, PersonField pf
  WHERE pf.PersonFieldKey NOT IN 
  (select PersonFieldKey FROM PersonFieldValue WHERE PersonKey = p.PersonKey)
  AND (pf.IsRequired = 1 or pf.IsLateRequirement = 1)

答案 1 :(得分:0)

下面的查询将完成这项工作,我测试了它[假设它为oracle]:

SELECT a.KEY,description FROM(
SELECT decode(personKey,1,2,personKey) KEY,personFieldKey
FROM PersonFieldValue
UNION
SELECT decode(personKey,2,1,personKey) KEY,personFieldKey
FROM PersonFieldValue) a, PersonField c
WHERE NOT EXISTS (SELECT 1 FROM PersonFieldValue b
                   WHERE a.KEY=b.personkey 
                  AND a.personfieldkey = b.personfieldkey)
and (isRequired=1 OR isLateRequirement=1)
and c.personFieldKey=a.personFieldKey;

对于那些想要测试的人,可以按照脚本生成模式:

create table PersonFieldValue (personKey number, personFieldKey number);

create table perseon(personKey number);

create table personfield(personFieldKey number,description varchar2(100),isRequired number, isLateRequirement number);

insert into personField values(1,'thing1',1,0);
insert into personField values(2,'thing2',0,1);
insert into personField values(3,'thing3',1,0);
insert into personField values(4,'thing4',0,0);

insert into PersonFieldValue values(1,3);
insert into PersonFieldValue values(1,4);
insert into PersonFieldValue values(2,1);
insert into PersonFieldValue values(2,2);