2014-01-07 134 views
1

晚上好,SQL:在一個聲明中加入人員,培訓和絕對培訓表格?

我打賭一個類似的問題已發佈之前,我只是找不到它。我目前正在努力處理以下情況: 我需要加入一張包含員工的表格,其中包含員工可以預訂的另一個表格,其中包含可由員工預訂的內部培訓,並且理想情況下使用另一個表格,其中包含針對每個人員和培訓的已接受培訓的培訓記錄。

樣品結構:

table "person" 
    -> person_id 
    -> last_name 
    -> first_name 

table "training" 
    -> training_id 
    -> training_name 

table "person2training" 
    -> person_ref 
    -> training_ref 

樣本數據:

person: 
    -> person_id: 1, last_name: Muller, first_name: Peter 
    -> person_id: 2, last_name: Schmitz, first_name: Horst 

training: 
    -> training_id: 1, training_name: "Sorting books" 
    -> training_id: 2, training_name: "Licking stamps" 

person2training: 
    -> person_ref: 2, training_ref: 2 

期望的結果(垂直地接合):

person_id | training_1 | training_2 
-----------|---------------|---------- 
1   | NULL   | NULL 
2   | NULL   | 1 (or true) 

表存儲在Oracle 11g數據庫,現在我在PHP中使用array_merge()創建「Desired Result」中顯示的數據,但是我認爲純粹的SQL解決方案是可行的隨着員工和培訓數量的不斷增加,員工的工作表現更好

提前致謝!

+1

是否有任何真正的方法,這些鏈接在一起? – Zane

+0

當然。我想人力資源部門或培訓中心的記錄會顯示這一點。它需要一些旋轉工作或從xml中選擇我猜。 – vasin1987

+0

@ vasin1987你是完全正確的,這是一個培訓中心。這個想法是創建一個包含相關參與狀態的受訓人員和培訓的所有可能組合的矩陣。 – SaschaM78

回答

0

假設OP試圖找到如果所有用戶培訓了1和2

我不認爲你需要爲你所需要的信息全部3個表。試試這個

SELECT 
    p.person_id, 
    (SELECT 1 FROM person2training pt 
     WHERE p.person_id = pt.person_id AND pt.training_id = 1) [training_1], 
    (SELECT 1 FROM person2training pt 
     WHERE p.person_id = pt.person_id AND pt.training_id = 2) [training_2] 
FROM person p 

你也可以用LEFT OUTER JOIN得到相同的結果。

SELECT 
    p.person_id, 
    CASE WHEN pt1.person_id IS NOT NULL THEN 1 ELSE NULL END [training_1], 
    CASE WHEN pt2.person_id IS NOT NULL THEN 1 ELSE NULL END [training_2] 
FROM person p 
    LEFT JOIN person2training pt1 ON p.person_id = pt1.person_id AND pt1.training_id = 1 
    LEFT JOIN person2training pt2 ON p.person_id = pt2.person_id AND pt2.training_id = 2 

EDIT:使用PIVOT查詢,當訓練手之前是未知的。
使用LEFT OUTER JOIN因爲可能有人沒有任何培訓。

SELECT * 
FROM (SELECT p.person_id, pt.training_ref 
     FROM person p 
      LEFT OUTER JOIN person_training pt ON p.person_id = pt.person_ref) 
PIVOT (COUNT(training_ref) AS trained FOR (training_ref) IN (SELECT training_id 
                  FROM training)) 
+0

您忘記了培訓表可以包含無限數量的培訓,因此靜態SQL不會這樣做。 – SaschaM78

+1

@ SaschaM78然後,您完成加入後,您的解決方案必須爲'PIVOT'。即使在這種情況下,您應該知道事先存在的培訓,「無限制」可能無法正常工作。 – user2989408

+0

我認爲使用PIVOT將成爲我的解決方案的一部分,並且使用PHP添加參與記錄數據可能是最佳選擇。感謝您指點我的PIVOT條款,我從來沒有聽說過它,它可能是非常有用的! – SaschaM78