2010-08-29 55 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