2011-08-09 51 views
10

Como ahora sé, CASE solo se puede usar en contexto WHERE. Sin embargo, necesito usar una tabla diferente según el valor column. Lo que he tratado es el siguiente:Consulta de MySQL donde JOIN depende de CASE

SELECT 
    `ft1`.`task`, 
    COUNT(`ft1`.`id`) `count` 
FROM 
    `feed_tasks` `ft1` 
CASE 
    `ft1`.`type` 
WHEN 
    1 
THEN 
    (INNER JOIN `pages` `p1` ON `p1`.`id` = `ft1`.`reference_id`) 
WHEN 
    2 
THEN 
    (INNER JOIN `urls` `u1` ON `u1`.`id` = `ft1`.`reference_id`) 
WHERE 
    `ft1`.`account_id` IS NOT NULL AND 
    `a1`.`user_id` = {$db->quote($user['id'])} 

Ahora que sé que esto es una sintaxis no válida, ¿cuál es la alternativa más cercana?

+1

debe combinar tanto '' pages' y urls' – ajreal

+1

¿Dónde se lee ese caso sólo puede utilizarse en WHERE ¿cláusulas? No es verdad –

+0

fusionar como literalmente "fusionar dos bases de datos en una"? Bueno, en ese caso, esta no es una opción porque ambos tienen una estructura completamente diferente. @ Álvaro G. Vicario: de cualquier manera, esta no es una sintaxis válida. Por lo tanto, estoy pidiendo una alternativa. – Gajus

Respuesta

11

Probablemente necesita un retoque para devolver los resultados correctos, pero espero que la idea:

SELECT ft1.task, COUNT(ft1.id) AS count 
FROM feed_tasks ft1 
LEFT JOIN pages p1 ON ft1.type=1 AND p1.id = ft1.reference_id 
LEFT JOIN urls u1 ON ft1.type=2 AND u1.id = ft1.reference_id 
WHERE COALESCE(p1.id, u1.id) IS NOT NULL 
AND ft1.account_id IS NOT NULL 
AND a1.user_id = :user_id 

Editar:

Una pequeña nota sobre CASE...END. El código original no se ejecuta porque, a diferencia de PHP o JavaScript, el SQL CASE no es una estructura de control de flujo que permite elegir qué parte del código se ejecutará. En cambio, devuelve una expresión. Así que usted puede hacer esto:

SELECT CASE 
    WHEN foo<0 THEN 'Yes' 
    ELSE 'No' 
END AS is_negative 
FROM bar 

... pero no esto:

-- Invalid 
CASE 
    WHEN foo<0 THEN SELECT 'Yes' AS is_negative 
    ELSE SELECT 'No' AS is_negative 
END 
FROM bar 
+0

funciona bien con dos combinaciones a la izquierda pero cuando agrego una tercera opción devuelve un error –

+0

@YosraNagati No hay nada en la sintaxis de combinación que lo restrinja a un número dado de tablas. El mensaje de error probablemente se deba a un error en tu código. –

1

Uso combinaciones externas en ambas mesas y mover el CASE dentro de su COUNT:

SELECT 
    ft1.task, 
    COUNT(case ft1.id when 1 then p1.id when 3 then u1.id end) as count 
FROM feed_tasks ft1 
LEFT JOIN pages p1 ON p1.id = ft1.reference_id 
LEFT JOIN urls u1 ON u1.id = ft1.reference_id 
WHERE ft1.account_id IS NOT NULL 
AND a1.user_id = {$db->quote($user['id'])} 

no-hits para el CASE darán una identificación null y no serán contados.

Nota: Tabla a1 está en su cláusula where, pero no parece ser una tabla seleccionada