2010-08-29 26 views
7

¿Hay una mejor manera de hacerlo?Devolviendo varias columnas desde SELECT anidado dentro de 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 

Idealmente me gustaría tener sólo una CASE sección que regresó nombre y correo electrónico de la tabla correspondiente.

Respuesta

4

yo usaría externa izquierda se une a ambos cuadros:

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 

En cuanto a la sólo un caso deseo, si se necesitan dos columnas distintas en su conjunto de resultados, se necesitan dos case frases.

+0

Gracias por su respuesta, que funciona bien. Sin embargo, no estoy seguro de haberlo entendido totalmente. ¿Las uniones "LEFT OUTER" solo se realizan si la comparación dentro de sus respectivos paréntesis evalúa "verdadero"? –

+0

Aha! Creo que lo entiendo ahora El caso 'agrega' selecciones a la parte SELECCIONAR, por lo que si 'subs.member_type = 'member'' entonces el bit SELECT será:' subs. *, M.nombre de usuario, m.email'. Por lo tanto, el 'LEFT OUTER' en ma se ejecutará pero no se incluirá en el conjunto de resultados. ¿Derecha? Supongo que esto no tendrá ningún impacto en el rendimiento ya que todas las columnas '* .id' son' primary_keys'? –

2

No puede usar una expresión de caso único para manejar dos columnas separadas ...

Uso:

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 
Cuestiones relacionadas