web-dev-qa-db-ja.com

ネストされたサブクエリに値を渡す

次のクエリがあります(簡潔にするために省略されています)。その目的は、結果の順序付けに使用されるw8値を作成することです。

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

私が抱えている問題は、2番目のネストされたサブクエリ(左側の結合の1つ)が最初の選択から列elements.idを見つけられないことです。

SQLの検索では、1レベルの深さの値しか渡さないことがわかったので、適切な回避策を見つけることができませんでした。

SQLに1レベルよりも深い値を渡すように強制することは可能ですか?または、別のサブクエリを使用せずに同じ結果を得るようにクエリを変更する方法はありますか?

バカなことをしたり、明らかなことを逃したりした場合、申し訳ありませんが、SQLは私の強みではありません。

4
Tam

私の知る限りでは、この制限は特にMySQLのSQLに関係しています。私が知っている他のすべてのSQL製品にはありません。

この問題に対する一般的な解決策はないようです。MySQLで列参照を1レベルよりも深く認識させることはできません。ただし、特定のケースでは簡単な回避策があります。最も内側のクエリのelements.idcraft_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

値を渡すクエリのフィルターに基づいて、INサブクエリに渡されるcraft_w8_a.elementIdelements.idに一致するため、これは同等の代替です。

4
Andriy M