2011-04-07 121 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