Peewee select 具有多个连接和多个计数的查询
Peewee select query with multiple joins and multiple counts
我一直在尝试编写一个 peewee select 查询,结果 table 有 2 个计数(一个用于与彩票相关的奖品数量,一个用于与彩票关联的包),以及彩票模型中的字段。
我已经成功编写了 select 查询,其中有 1 个计数有效(见下文),然后我不得不将 ModelSelects 转换为列表并手动加入它们(我认为这非常 hacky) .
我确实设法写了一个 select 查询,其中连接了结果,但它会将包裹数乘以奖品数(我已经丢失了该查询)。
我也尝试过使用 .switch(Lottery),但我没有任何运气。
query1 = (Lottery.select(Lottery,fn.count(Package.id).alias('packages'))
.join(LotteryPackage)
.join(Package)
.order_by(Lottery.id)
.group_by(Lottery)
.dicts())
query2 = (Lottery.select(Lottery.id.alias('lotteryID'), fn.count(Prize.id).alias('prizes'))
.join(LotteryPrize)
.join(Prize)
.group_by(Lottery)
.order_by(Lottery.id)
.dicts())
lottery = list(query1)
query3 = list(query2)
for x in range(len(lottery)):
lottery[x]['prizes'] = query3[x]['prizes']
虽然上面的代码有效,但是有没有更简洁的方法来编写这个查询?
最好的办法是使用子查询。
# Create query which gets lottery id and count of packages.
L1 = Lottery.alias()
subq1 = (L1
.select(L1.id, fn.COUNT(LotteryPackage.package).alias('packages'))
.join(LotteryPackage, JOIN.LEFT_OUTER)
.group_by(L1.id))
# Create query which gets lottery id and count of prizes.
L2 = Lottery.alias()
subq2 = (L2
.select(L2.id, fn.COUNT(LotteryPrize.prize).alias('prizes'))
.join(LotteryPrize, JOIN.LEFT_OUTER)
.group_by(L2.id))
# Select from lottery, joining on each subquery and returning
# the counts.
query = (Lottery
.select(Lottery, subq1.c.packages, subq2.c.prizes)
.join(subq1, on=(Lottery.id == subq1.c.id))
.join(subq2, on=(Lottery.id == subq2.c.id))
.order_by(Lottery.name))
for row in query.objects():
print(row.name, row.packages, row.prizes)
我一直在尝试编写一个 peewee select 查询,结果 table 有 2 个计数(一个用于与彩票相关的奖品数量,一个用于与彩票关联的包),以及彩票模型中的字段。
我已经成功编写了 select 查询,其中有 1 个计数有效(见下文),然后我不得不将 ModelSelects 转换为列表并手动加入它们(我认为这非常 hacky) .
我确实设法写了一个 select 查询,其中连接了结果,但它会将包裹数乘以奖品数(我已经丢失了该查询)。
我也尝试过使用 .switch(Lottery),但我没有任何运气。
query1 = (Lottery.select(Lottery,fn.count(Package.id).alias('packages'))
.join(LotteryPackage)
.join(Package)
.order_by(Lottery.id)
.group_by(Lottery)
.dicts())
query2 = (Lottery.select(Lottery.id.alias('lotteryID'), fn.count(Prize.id).alias('prizes'))
.join(LotteryPrize)
.join(Prize)
.group_by(Lottery)
.order_by(Lottery.id)
.dicts())
lottery = list(query1)
query3 = list(query2)
for x in range(len(lottery)):
lottery[x]['prizes'] = query3[x]['prizes']
虽然上面的代码有效,但是有没有更简洁的方法来编写这个查询?
最好的办法是使用子查询。
# Create query which gets lottery id and count of packages.
L1 = Lottery.alias()
subq1 = (L1
.select(L1.id, fn.COUNT(LotteryPackage.package).alias('packages'))
.join(LotteryPackage, JOIN.LEFT_OUTER)
.group_by(L1.id))
# Create query which gets lottery id and count of prizes.
L2 = Lottery.alias()
subq2 = (L2
.select(L2.id, fn.COUNT(LotteryPrize.prize).alias('prizes'))
.join(LotteryPrize, JOIN.LEFT_OUTER)
.group_by(L2.id))
# Select from lottery, joining on each subquery and returning
# the counts.
query = (Lottery
.select(Lottery, subq1.c.packages, subq2.c.prizes)
.join(subq1, on=(Lottery.id == subq1.c.id))
.join(subq2, on=(Lottery.id == subq2.c.id))
.order_by(Lottery.name))
for row in query.objects():
print(row.name, row.packages, row.prizes)