我想有一个简单的子查询。我想在几个地方重复使用。有些是连接,有些不是。
SQL代码应该是这样的
SELECT IF(x, y, z) as foo, table.*
FROM TABLE
WHERE condition
然后它被用在很多地方,通过foo连接和where。
有时简单地像这样:
SELECT * FROM
(
SELECT IF(x, y, z) as foo, table.*
FROM TABLE
WHERE condition
) WHERE (foo > 100)
有时更复杂,如分组、连接。
然而,我发现在wee中很难做到这一点。
我发现我可以这样做如果我使用join
query1 = table1.select(...).where(...)
query2 = table2.select(...).join(query1, on=(...))...
query1 = table1.select(...).where(...)
query2 = query1.select(...).join(table2, on=(...))...
也可以
然而,如果我只是从query1中选择,它不起作用。失败的确切代码:
query = tables.Payments.select(fn.IF(tables.Payments.payment_status > 0, tables.Payments.payment_amount, -tables.Payments.payment_amount).alias("x")).where(tables.Payments.payment_amount > 200)
query2 = query.select().where(query.c.x < 0)
我希望query2只是一个选择从支付x,根据之前的条件计算,是小于0,但相反,它产生虚假的SQL代码
SELECT FROM `payments` AS `t1` WHERE ((`t1`.`payment_amount` > 200) AND (`t2`.`x` < 0))
这显然是错误的,不会执行
我该怎么做?这在peewee有可能吗?
我知道我可以写&;where()&;并在那里复制我的条件,但这是不好的做法,因为它是复制代码,如果我以后想改变那个条件怎么办?我要在10个地方重做吗?肯定有合适的方法来做这件事
PS:根据建议,我已经改变了我的代码,但它又产生了错误的SQL查询。
我的代码:
query = tables.Payments.select(fn.IF(tables.Payments.payment_status > 0, tables.Payments.payment_amount, -tables.Payments.payment_amount).alias("x")).where(tables.Payments.payment_amount > 200)
query2 = query.select_from(query.c.x).where(query.c.x < 0)
结果查询:
SELECT `t1`.`x` FROM (SELECT IF((`t2`.`payment_status` > 0), `t2`.`payment_amount`, `t2`.`payment_amount` DESC) AS `x` FROM `payments` AS `t2` WHERE (`t2`.`payment_amount` > 200)) AS `t1` WHERE (`t1`.`x` < 0)
正如你所看到的,它没有做减号操作,而是添加了DESC,这显然是不对的。
如何解决这个问题?
下面是一个使用select_from()
包装子查询的示例:
db = SqliteDatabase(':memory:')
class Reg(db.Model):
key = TextField()
db.create_tables([Reg])
Reg.create(key='k1')
Reg.create(key='k2')
Reg.create(key='k3')
subq = Reg.select(Reg.key.alias('foo'), Reg)
query = subq.select_from(subq.c.foo).where(subq.c.foo.in_(['k1', 'k3']))
for row in query:
print(row.foo)
# k1
# k3
另一个例子,这基本上是select_from()
在引擎盖下所做的:
query = Select([subq], [subq.c.foo]).bind(db)
for row in query:
print(row)
# {'foo': 'k1'}
# {'foo': 'k2'}
# {'foo': 'k3'}
对于您的问题的最后一次/最近一次编辑,用X * -1替换一元减号:
query = (Payments.select(fn.IF(
Payments.payment_status > 0,
Payments.payment_amount,
Payments.payment_amount * -1).alias("x")
).where(Payments.payment_amount > 200)
query2 = query.select_from(query.c.x).where(query.c.x < 0)