2011-08-09 43 views
10

正如我現在知道的,CASE只能在WHERE上下文中使用。雖然,我需要根據column值使用不同的表格。我試過的樣子是這樣的:MySQL查詢在何處JOIN取決於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'])} 

現在我知道這是無效的語法,最接近的選擇是什麼?

+1

你應該合併兩個'pages'和'urls' – ajreal

+1

你在哪裏讀到情況下,可以僅在使用條款?這不是真的。 –

+0

合併爲字面意義上的「將兩個數據庫合併爲一個」?那麼在這種情況下,這不是一種選擇,因爲它們的結構完全不同。 @ÁlvaroG. Vicario:無論哪種方式,這都是無效的語法。因此我正在尋求替代方案。 – Gajus

回答

11

它可能需要調整,以返回正確的結果,但我希望你的想法:

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 
+0

它可以很好地處理兩個左連接,但是當我添加第三個選擇時,它將返回錯誤 –

+0

@YosraNagati連接語法中沒有任何內容將它限制爲給定數量的表。該錯誤消息可能是由於您的代碼中存在錯誤。 –

1

使用外連接的表和移動CASECOUNT內:

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子句中,但似乎並沒有成爲一個選擇的表