2011-04-07 69 views
0

我有一个表P,带有personid列和licensetypeid列。Self加入PLSQL

每个人可以有多个许可证类型,为该人员ID添加额外的行到表中。

我需要找到PERSONID有1两licenseid的5

,行,我不能写:

SELECT personid, licensetypeid 
FROM P 
WHERE licensetypeid=1 AND licensetypeid=5; 

听说我应该使用自联接做到这一点。我如何做自我加入来解决这个问题?

回答

0

试试这个

select personid,licensetypeid from P where licensetypeid in ('1','5') 
+0

。谢谢你的答案。否则它将采取具有licenseid 1或5的条目。我需要得到具有许可证 – Remya 2011-04-07 11:33:21

+0

@Remya的personid这是1和5是恒定的还是动态的,如它可以是1,5 (如你的情况)或有时只有1或有时1,2,5? – ashishjmeshram 2011-04-07 12:11:36

+0

是的,它像一些员工可以有许可证1只有一些可以有5只有一些都有。我需要同时拥有许可证的员工,但许可证ID不变(1,5等) – Remya 2011-04-07 12:16:49

2
select personid, licensetypeid 
from P P1 
where exists (
    select 1 
    from P P2 
    where P2.personid = P1.personid 
     and P2.licensetypeid = 1 
) and exists (
    select 1 
    from P P2 
    where P2.personid = P1.personid 
     and P2.licensetypeid = 5 
) 
+0

嗨感谢您的回复。但我很困惑。这是什么P1?该表是查询中使用的表名吗?你可以请expalin – Remya 2011-04-07 12:13:57

+0

对不起,语法错误那里,我编辑了答案“P P1”等。 – 2011-04-07 12:31:35

+0

使用EXISTS子句 – 2011-04-07 14:26:14

1
SELECT distinct 
     p1.personid 
     ,p1.licensetypeid 
     ,p2.licensetypeid 
from P p1, P p2 
WHERE p1.personid = p2.personid 
AND p1.licensetypeid = 1 
AND p2.licensetypeid = 5 
; 
+0

嗨这一个工作我猜。感谢您的帖子..非常感谢 – Remya 2011-04-07 12:19:12

0

如果您需要的许可类型设置为“固定”,或者至少如果设定所需的许可证类型的基数是固定的,那么给答案会正常工作。

否则,您需要编写被称为“关系分割”的SQL等价物。

那去如下:

(1)计算的一组缺少所需的许可证类型中的至少一个人的:

SELECT personid 
from P 
WHERE EXISTS 
    (
    SELECT licenseid 
    from NEEDEDLICENSETYPE AS NLT 
    WHERE NOT EXISTS (
     SELECT * 
     FROM P AS PBIS 
     WHERE 
     PBIS.personid = P.personid AND 
     PBIS.licensetype = NLT.licensetype 
    ) 
) 

NEEDELICENSETYPE代表任何SQL语句,你需要计算集的特定调用所需的许可类型。

(2)选择一个数字,没有出现在(1)人员的数据:

SELECT ... FROM P WHERE personid NOT IN (...) 
+0

对于题外话的问题感到抱歉,但是您是否为您给出的每个答案创建了一个新用户,或者是“Erwin Smout”在某个国家是一个非常常见的名字? ;-) – Ronnis 2011-04-07 18:32:39

4

自连接和访问表不止一次将工作的其他技术,但可能降低性能,并且如果需要推广到更大的ID集,则很难实现。

可通过计算每个人相匹配的行数与一个参考表做:

select personid from P 
    where licensetypeid in ('1','5') 
    group by personid 
    having count(*) = 2 

这可以很容易地扩展,如果你想需要更大的licensetypeid值:

select personid from P 
    where licensetypeid in ('1','5','7') 
    group by personid 
    having count(*) = 3 

(在自连接的版本,你就必须添加一个额外加入每增加值)

或者,如果你想找到具有在人至少有2种出更大的一组类型:

select personid from P 
    where licensetypeid in ('1','5', '7', '10') 
    group by personid 
    having count(*) >= 2 

现在,不像你的样品查询时,licensetypeid不包括在结果集中。如果由于某种原因是必要的,你可以做一个简单的技巧在2个值的情况下:

select personid, min(licensetypeid) licensetype1, max(licensetypeid) licensetype2 
    from P 
    where licensetypeid in ('1','5') 
    group by personid 
    having count(*) = 2 

但更普遍的做法是,把值到一个简单的集合:

select personid, collect(licensetypeid) licensetypeidlist 
    from P 
    where licensetypeid in ('1','5') 
    group by personid 
    having count(*) = 2