所以,我编写了一个非常复杂的查询,它从两个表中获取并加入了大量数据。
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的核心。
答案 0 :(得分:2)
您可以使用the case
function在查询中添加条件。这不会产生您提供的SQL,但可以产生功能相当的东西。
以下是一个简单示例,carrier
和rsu
变量引用Table
个对象,case
引用上述函数:
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_)