2010-08-29 6 views
7

Gibt es eine bessere Möglichkeit, dies zu tun?Mehrere Spalten aus SELECT zurückgeben geschachtelt innerhalb CASE 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 

Im Idealfall würde Ich mag nur eine CASE Abschnitt haben, die Namen und E-Mail aus der entsprechenden Tabelle zurückgegeben.

Antwort

4

würde ich links Outer-Joins auf beiden Tabellen verwenden:

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 

den Wunsch nur in einem Fall In Bezug auf, wenn Sie benötigen zwei verschiedene Spalten auf Ihrem resultset, werden Sie zwei case Sätze benötigen. zwei separate Spalten

+0

Vielen Dank für Ihre Antwort, es funktioniert gut. Ich bin mir nicht sicher, ob ich es vollständig verstehe - sind die 'LEFT OUTER'-Joins nur dann gemacht, wenn der Vergleich innerhalb ihrer jeweiligen Klammern 'wahr' auswertet? –

+0

Aha! Ich denke, ich verstehe es jetzt. Der Fall "fügt" Selektionen zum SELECT-Teil hinzu. Wenn also "subs.member_type = 'member'", dann wird das SELECT-Bit: 'subs. *, M.username, m.email'. So wird der 'LEFT OUTER' auf ma ausgeführt, aber nicht in der Ergebnismenge enthalten. Recht? Ich nehme an, dass dies keine Auswirkungen auf die Performance haben wird, da alle '* .id' Spalten 'primary_keys' sind? –

2

Sie können nicht einen einzigen Fall Ausdruck verwenden zu handhaben ...

Verwendung:

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