11 Stimmen

MySQL-Abfrage, bei der JOIN von CASE abhängt

Wie ich jetzt weiß, kann CASE nur im WHERE-Kontext verwendet werden. Allerdings muss ich je nach Wert von column eine andere Tabelle verwenden. Das, was ich versucht habe, sieht so aus:

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'])}

Jetzt, da ich weiß, dass dies ungültige Syntax ist, was ist die nächstbeste Alternative?

15voto

Álvaro González Punkte 134708

Es muss wahrscheinlich angepasst werden, um die richtigen Ergebnisse zurückzugeben, aber ich hoffe, du bekommst die Idee:

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

Bearbeiten:

Eine kleine Anmerkung zu CASE...END. Ihr Originalcode funktioniert nicht, weil, anders als in PHP oder JavaScript, das SQL CASE keine Ablaufsteuerungsstruktur ist, die es ermöglicht, auszuwählen, welcher Teil des Codes ausgeführt wird. Stattdessen gibt es einen Ausdruck zurück. Also können Sie das tun:

SELECT CASE
    WHEN foo<0 THEN 'Ja'
    ELSE 'Nein'
END AS is_negative
FROM bar

... aber nicht das:

-- Ungültig
CASE 
    WHEN foo<0 THEN SELECT 'Ja' AS is_negative
    ELSE SELECT 'Nein' AS is_negative
END
FROM bar

1voto

Bohemian Punkte 386825

Verwenden Sie äußere Joins auf beiden Tabellen und verschieben Sie das CASE in Ihren 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'])}

Nicht-Treffer für den CASE werden eine null-ID liefern und nicht gezählt werden.

Hinweis: Die Tabelle a1 befindet sich in Ihrer WHERE-Klausel, wird aber nicht als ausgewählte Tabelle angezeigt.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X