Self加入PLSQL
我有一个表P,带有personid列和licensetypeid列。Self加入PLSQL
每个人可以有多个许可证类型,为该人员ID添加额外的行到表中。
我需要找到PERSONID有1两licenseid的5
,行,我不能写:
SELECT personid, licensetypeid
FROM P
WHERE licensetypeid=1 AND licensetypeid=5;
听说我应该使用自联接做到这一点。我如何做自我加入来解决这个问题?
试试这个
select personid,licensetypeid from P where licensetypeid in ('1','5')
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
)
嗨感谢您的回复。但我很困惑。这是什么P1?该表是查询中使用的表名吗?你可以请expalin – Remya 2011-04-07 12:13:57
对不起,语法错误那里,我编辑了答案“P P1”等。 – 2011-04-07 12:31:35
使用EXISTS子句 – 2011-04-07 14:26:14
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
;
嗨这一个工作我猜。感谢您的帖子..非常感谢 – Remya 2011-04-07 12:19:12
如果您需要的许可类型设置为“固定”,或者至少如果设定所需的许可证类型的基数是固定的,那么给答案会正常工作。
否则,您需要编写被称为“关系分割”的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 (...)
对于题外话的问题感到抱歉,但是您是否为您给出的每个答案创建了一个新用户,或者是“Erwin Smout”在某个国家是一个非常常见的名字? ;-) – Ronnis 2011-04-07 18:32:39
自连接和访问表不止一次将工作的其他技术,但可能降低性能,并且如果需要推广到更大的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
。谢谢你的答案。否则它将采取具有licenseid 1或5的条目。我需要得到具有许可证 – Remya 2011-04-07 11:33:21
@Remya的personid这是1和5是恒定的还是动态的,如它可以是1,5 (如你的情况)或有时只有1或有时1,2,5? – ashishjmeshram 2011-04-07 12:11:36
是的,它像一些员工可以有许可证1只有一些可以有5只有一些都有。我需要同时拥有许可证的员工,但许可证ID不变(1,5等) – Remya 2011-04-07 12:16:49