2017-07-11 90 views
0

我對sql查詢有一個問題,對我來說這似乎很簡單,但無法讓它正常工作。錶行之間的SQL連接

所以我有這個表:

enter image description here broadcast_media_id告訴我,如果該數據爲1 - 電子郵件或2 - 電話。我需要爲一名員工收集電子郵件和電話(使用相同的employee_id)。

我想查詢是這樣的:

SELECT DISTINCT ed.employee_id, 
    ed.text_value AS email, 
    x.text_value AS phone 
FROM employee_data ed 
    INNER JOIN 
     (
      SELECT employee_id, 
       text_value 
      FROM employee_data 
      WHERE broadcast_media_id = 2 
     ) x ON x.employee_id = ed.employee_id 
WHERE broadcast_media_id = 1 

,因爲不幸的是,WHERE子句我得到的值只有當員工有一個電子郵件。所以,結果是這樣的:

enter image description here

我失蹤「A773B230-754C-423F-97C4-E331268EA3C8」的手機價值,只是因爲他沒有電子郵件。我也想顯示這一行,電子郵件的值爲NULL。

這似乎很簡單,但我不明白。

我感謝您的幫助。

+1

使用'留下join'然後 –

回答

1

如果您想用join,可以用LEFT JOIN

SELECT ed.employee_id, ede.text_value AS email, 
     edp.text_value AS phone 
FROM employees e LEFT JOIN 
    employee_data ede 
    ON ede.employee_id = e.employee_id AND 
     ede.broadcast_media_id = 1 LEFT JOIN 
    employee_data edp 
    ON edp.employee_id = e.employee_id AND 
     edp.broadcast_media_id = 2 

注意:這假定您有一個employees表 - 這看起來非常合理。這對於LEFT JOIN非常方便。這可能會有最好的表現。

如果您沒有employees表,請使用子查詢(SELECT DISTINCT employee_id FROM employee_data)

我會傾向於使用條件聚合來實現這一點,這應該也有合理的性能。

+0

我有員工表是,但我不想讓它涉及。 這似乎工作: SELECT DISTINCT ed.employee_id,ede.text_value電子郵件,edp.text_value AS電話 FROM employee_data版 LEFT JOIN employee_data義德ON ede.employee_id = ed.employee_id和ede.broadcast_media_id = 1個 LEFT加入employee_data edp ON edp.employee_id = ed.employee_id AND edp.broadcast_media_id = 2 謝謝 – Binev

+0

@IvanBinev。 。 。如果你關心績效,那麼員工表將會更有效率。 –

+0

嗯,我這樣做,但離開加入不會這樣做,因爲員工可能沒有電話和電子郵件,我不想向沒有任何員工的員工展示。 – Binev

1

如果員工總是有電話,只需使用LEFT JOIN即可。

SELECT DISTINCT ed.employee_id, 
    ed.text_value AS email, 
    x.text_value AS phone 
FROM employee_data ed 
    LEFT JOIN 
     (
      SELECT employee_id, 
       text_value 
      FROM employee_data 
      WHERE broadcast_media_id = 2 
     ) x ON x.employee_id = ed.employee_id 
WHERE broadcast_media_id = 1 

您也可避免自行加入,但最有可能的表現會更糟糕

SELECT ed.employee_id, 
     MIN(CASE WHEN broadcast_media_id = 1 THEN text_value END) AS phone, 
     MIN(CASE WHEN broadcast_media_id = 2 THEN text_value END) AS email 
FROM employee_data ed 
GROUP BY ed.employee_id 

如果員工可以沒有手機,那麼你可以使用FULL JOIN

SELECT DISTINCT 
    COALESCE(ed.employee_id, x.employee_id) employee_id, 
    ed.text_value AS email, 
    x.text_value AS phone 
FROM 
    (SELECT * FROM employee_data WHERE broadcast_media_id = 1) ed 
    FULL JOIN (SELECT * FROM employee_data WHERE broadcast_media_id = 2) x 
     ON x.employee_id = ed.employee_id; 
+1

員工可以沒有電話或/和沒有電子郵件。 我試過FULL JOIN,但它給我只有兩行相同的結果(因爲'WHERE broadcast_media_id = 1'從其他連接中刪除行)。 您建議的第二個查詢正常。 你說爲什麼表現會更糟? – Binev

+0

謝謝你的答案MIN答案工作,但我接受了沒有集合函數的另一個答案。這是非常好的選擇,絕對有用! – Binev

+0

新增FULL JOIN示例 –

1

嘗試此查詢 - 我沒有使用任何聯接儘管

Select 
    EmpID, 
    Max(Case When MediaID = 1 Then TextValue End) As EmailID, 
    Sum(Case When MediaID = 2 Then Cast(TextValue As Int) End) As PhoneNumber 
From employee_data 
Group By EmpID 
Order By EmpID; 

這裏 - 排序= 78%和表掃描= 22%的成本。 (我的實例數據,它肯定會隨着你的系統和數據而變化。)

如果你做了一些索引,那麼它的性能會更好。

0

我會用一個雙LEFT JOIN,如:

SELECT ed.employee_id 
      ,COALESCE(ed1.text_value,'') as mail 
      ,COALESCE(ed2.text_value,'') as phone 
     FROM employee_data ed 
LEFT JOIN employee_data ed1 
     ON ed.employee_id = ed1.employee_id 
     AND ed1.broadcast_media_id = 1 
LEFT JOIN employee_data ed2 
     ON ed.employee_id = ed2.employee_id 
     AND ed2.broadcast_media_id = 2