0

そこで、2 つのテーブルから大量のデータを取得して結合する非常に複雑なクエリを作成しました。

SELECT
    /* Common attributes */
    carrier.name,
    carrier.notes,
    carrier.turnaround,

    /* Either per-reseller price, generic reseller price or default price */
    IFNULL(
        rsu.price,
        IF(
            (
                carrier.reseller_price != IS NOT NULL AND
                carrier.reseller_price != 0
            ),
            carrier.reseller_price,
            carrier.price
        )
    ) AS price,
    IFNULL(
        rsu.price_barred,
        IF(
            (
                carrier.reseller_price_barred IS NOT NULL AND
                carrier.reseller_price_barred != 0
            ),
            carrier.reseller_price_barred,
            carrier.price_barred
        )
    ) AS price_barred
FROM
    `core_carrier` AS carrier
LEFT OUTER JOIN
    `core_resellerunlock` AS rsu ON (
        rsu.carrier_id = carrier.id AND
        rsu.reseller_id = 1
    )

誰かが SQLAlchemy クエリビルダーを使用してこれを書き直す方法を提案できますか? SELECT ... IFそれらの条項でさえ可能かどうかはわかりません。

編集: ORM を使用してこれを実行したくありません (私の知る限り、これを SQLAlchemy ORM を使用して純粋に実行することはできません)。私は、SQLAlchemy のコアを使用してこれを行う多かれ少なかれ移植可能な方法を探しています。

4

1 に答える 1

2

関数を使用してcase、クエリに条件を含めることができます。これは、提示した SQL を正確に生成するわけではありませんが、機能的に同等のものを生成できます。

オブジェクトを参照し、前述の関数を参照するcarrierおよびrsu変数を使用した簡単な例を次に示します。Tablecase

join = carrier.join(rsu, (rsu.c.carrier_id == carrier.c.id) & (rsu.c.reseller_id == 1))
query = join.select([
    carrier.c.name,
    carrier.c.notes,
    carrier.c.turnaround,
    case([
        (
            rsu.c.price_barred == None,
            case([
                (
                    (carrier.c.reseller_price != None) & (carrier.c.reseller_price != 0),
                    carrier.c.reseller_price
                )
            ],
            else_=carrier.c.price
        )
    ]
])

高レベルを表すヘルパー関数と、クエリの読みやすさを向上させる関数を作成すると便利な場合がIFNULLありIFます。例えば:

def if_(expr, then, else_):
    return case([
        (expr, then)
    ], else_=else_)
于 2013-03-17T02:09:10.170 に答える