Запрос MySQL, в котором JOIN зависит от CASE
Как мне теперь известно, CASE можно использовать только в контексте WHERE. Хотя мне нужно использовать другую таблицу в зависимости от значения column
. То, что я пробовал, выглядит так:
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'])}
Теперь, когда я знаю, что это недопустимый синтаксис, какая ближайшая альтернатива?
Ответы
Ответ 1
Вероятно, вам нужно настроить, чтобы вернуть правильные результаты, но я надеюсь, что вы поняли:
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
Edit:
Небольшая заметка о CASE...END
. Ваш исходный код не запускается, потому что, в отличие от PHP или JavaScript, SQL CASE
не является структурой управления потоком, которая позволяет выбирать, какая часть кода будет работать. Вместо этого он возвращает выражение. Итак, вы можете сделать это:
SELECT CASE
WHEN foo<0 THEN 'Yes'
ELSE 'No'
END AS is_negative
FROM bar
... но не это:
-- Invalid
CASE
WHEN foo<0 THEN SELECT 'Yes' AS is_negative
ELSE SELECT 'No' AS is_negative
END
FROM bar
Ответ 2
Используйте внешние соединения на обеих таблицах и переместите CASE
внутри своего 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'])}
Некшины для CASE
дадут id null
и не будут считаться.
Примечание. Таблица a1
находится в предложении where, но не является выбранной таблицей