MySQL查询JOIN取决于CASE

时间:2011-08-09 10:36:26

标签: mysql sql

我现在知道,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 个答案:

答案 0 :(得分:13)

可能需要调整以返回正确的结果,但我希望你明白这个想法:

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

修改

关于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 :(得分:1)

在两个表格上使用外部联接并移动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的非点击次数会产生null个ID,不会被计算在内。

注意:表a1位于where子句中,但似乎不是选定的表