MySQL запрос, где JOIN зависит от CASE - PullRequest
11 голосов
/ 09 августа 2011

Как я теперь знаю, 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'])}

Теперь, когда я знаю, что это недопустимый синтаксис, какова ближайшая альтернатива?

Ответы [ 2 ]

14 голосов
/ 09 августа 2011

Возможно, для получения правильных результатов нужно настроить, но я надеюсь, что вы поняли:

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
1 голос
/ 09 августа 2011

Используйте внешние объединения на обоих столах и переместите 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'])}

Non-hit для CASE даст идентификатор null и не будет засчитан.

Примечание. Таблица a1 находится в предложении where, но не является выбранной таблицей

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...