it-swarm.com.de

Übergeben eines Werts an eine verschachtelte Unterabfrage

Ich habe die folgende Abfrage (der Kürze halber reduziert), deren Ziel es ist, den Wert w8 Zu erstellen, der zum Ordnen der Ergebnisse verwendet wird:

SELECT elements.id, [ ... ],
(SELECT 
    COALESCE(craft_w8_a.weight, 0) + COALESCE(SUM(craft_w8_b.weight), 0) 
    FROM `craft_w8` `craft_w8_a`
    LEFT JOIN `craft_w8` `craft_w8_b` 
        ON craft_w8_b.elementId
        IN ( SELECT targetId FROM `craft_relations`
                WHERE fieldId IN (15, 16)
                  AND sourceId = elements.id)
    WHERE craft_w8_a.elementId = elements.id
) as w8
FROM `craft_elements` `elements`
[ ... ]
GROUP BY `elements`.`id`
ORDER BY `w8` DESC, `name` ASC LIMIT 100

Das Problem, das ich habe, ist, dass die zweite verschachtelte Unterabfrage (die im linken Join) die Spalte elements.id Aus der anfänglichen Auswahl nicht finden kann.

Nach dem, was ich bei der Suche in SQL gefunden habe, werden nur Werte auf einer Ebene übergeben, und ich konnte keine geeignete Problemumgehung finden.

Ist es möglich, SQL zu zwingen, einen Wert zu übergeben, der tiefer als eine Ebene ist? Oder gibt es eine Möglichkeit, die Abfrage so zu ändern, dass keine andere Unterabfrage verwendet wird, aber dennoch das gleiche Ergebnis erzielt wird?

Tut mir leid, wenn ich etwas Dummes tue oder etwas Offensichtliches verpasse, ist SQL nicht meine Stärke!

4
Tam

Meines Wissens betrifft diese Einschränkung SQL speziell in MySQL. Alle anderen mir bekannten SQL-Produkte haben es nicht.

Es scheint im Allgemeinen keine Lösung für dieses Problem zu geben: Sie können nicht erzwingen, dass eine Spaltenreferenz in MySQL tiefer als eine Ebene erkannt wird. In Ihrem speziellen Fall gibt es jedoch eine einfache Problemumgehung: Ersetzen Sie das elements.id In der innersten Abfrage durch craft_w8_a.elementId:

SELECT elements.id, [ ... ],
(SELECT 
    COALESCE(craft_w8_a.weight, 0) + COALESCE(SUM(craft_w8_b.weight), 0) 
    FROM `craft_w8` `craft_w8_a`
    LEFT JOIN `craft_w8` `craft_w8_b` 
        ON craft_w8_b.elementId
        IN ( SELECT targetId FROM `craft_relations`
                WHERE fieldId IN (15, 16)
                  AND sourceId = craft_w8_a.elementId)
    WHERE craft_w8_a.elementId = elements.id
) as w8
FROM `craft_elements` `elements`
[ ... ]
GROUP BY `elements`.`id`
ORDER BY `w8` DESC, `name` ASC LIMIT 100

Dies ist ein äquivalenter Ersatz, da alles, was craft_w8_a.elementId An die IN-Unterabfrage übergeben wird, mit elements.id Übereinstimmt, basierend auf dem Filter in der Abfrage, die den Wert übergibt.

4
Andriy M