2010-08-29 58 views
7

有沒有更好的方法來做到這一點?從SELECT中返回嵌套在SELECT中的多列MySQL

SELECT subs. * , 
     CASE subs.member_type 
     WHEN 'member' THEN 
     (SELECT CONCAT_WS(' ', members.first_name, members.last_name) 
      FROM members 
      WHERE members.id = subs.member_id) 
     ELSE 
     (SELECT members_anon.username 
      FROM members_anon 
      WHERE members_anon.id = subs.member_id) 
     END AS fullname, 
     CASE subs.member_type 
     WHEN 'member' THEN 
     (SELECT members.email 
      FROM members 
      WHERE members.id = subs.member_id) 
     ELSE 
     (SELECT members_anon.email 
      FROM members_anon 
      WHERE members_anon.id = subs.member_id) 
     END AS email 
    FROM subs 
WHERE subs.item_id =19 
    AND subs.item_type = 'blog' 
LIMIT 0 , 30 

理想情況下,我想只有一個CASE從相關表中返回的姓名和電子郵件部分。

回答

4

我會用左外連接兩個表:

SELECT subs. * , 
     CASE subs.member_type 
     WHEN 'member' THEN CONCAT_WS(' ', m.first_name, m.last_name) 
     ELSE ma.username 
     END AS fullname, 
     CASE subs.member_type 
     WHEN 'member' THEN m.email 
     ELSE ma.email 
     END AS email 
    FROM subs 
    LEFT OUTER JOIN members m on (m.id = subs.member_id) 
    LEFT OUTER JOIN members_anon ma on (ma.id = subs.member_id) 
WHERE subs.item_id =19 
    AND subs.item_type = 'blog' 
LIMIT 0 , 30 

關於僅有一例心願,如果你需要在你的結果集兩個不同的列,您將需要兩個case句子。

+0

謝謝您的回答,它工作得很好。我不確定我是否完全明白 - 是否只有在各自括號內的比較評估爲「真」時纔會進行「LEFT OUTER」連接? – 2010-08-29 23:26:02

+0

啊哈!我想我現在明白了。這種情況'SELECT'選擇部分,所以如果'subs.member_type ='member''那麼SELECT位將是:'subs。*,m.username,m.email'。因此,ma上的'LEFT OUTER'將被執行,但不包含在結果集中。對?我想這不會對性能造成任何影響,因爲所有'* .id'列都是'primary_keys'? – 2010-08-29 23:34:18

2

不能使用一個單一的情況下,表達式處理兩個單獨的列...

用途:

SELECT s. *, 
      CASE s.member_type 
      WHEN 'member' THEN x.fullname 
      ELSE y.fullname 
      END AS fullname, 
      CASE subs.member_type 
      WHEN 'member' THEN x.email 
      ELSE y.email 
      END AS email 
    FROM SUBS s 
LEFT JOIN (SELECT m.id, 
        CONCAT_WS(' ', members.first_name, members.last_name) AS fullname, 
        m.email 
      FROM MEMBERS m) x ON x.id = s.member_id 
LEFT JOIN (SELECT ma.id, 
        ma.username, 
        ma.email 
      FROM MEMBERS_ANON ma) y ON y.id = s.member_id       
    WHERE s.item_id = 19 
     AND s.item_type = 'blog' 
    LIMIT 0 , 30