python - SQLAlchemy:通过相互外键对两列的查询结果进行分组
问题描述
我正在尝试做的事情:
我在 Postgres 数据库中有 3 个表。
user
-----------------------
user_id name age
-----------------------
001 Alice 25
002 Bob 32
003 Colin 31
004 Danny 40
laundry_task
-----------------------------
task_id user_id completed
-----------------------------
101 001 true
102 003 false
103 001 true
cooking_task
-----------------------------
task_id user_id completed
-----------------------------
201 001 true
202 002 true
203 003 false
我需要 SQLAlchemy 向我返回一个元组列表,例如:
[(001, 2, 1), (002, 0, 1)]
元组包括:
0) user_id
1) number_of_times_laundry_task_completed
2) number_of_times_cooking_task_completed
或
[(001, 3), (002, 1)]
元组包括:
0) user_id
1) sum_of_times_boths_tasks_completed
我在一个查询中需要它。 (子查询没问题)
如果其中 1 个表中没有分配任务,completed
则应将 count 设置为 0。如果两个表中都没有分配任务,则元组应该看起来像(004, 0, 0)
(或(004, 0)
) 或根本不在列表中。
它在 2 个查询中的样子:
laundry_tasks = (
session.query(LaundryTask.user_id, func.count(LaundryTask.completed))
.filter(LaundryTask.completed == True)
.group_by(LaundryTask.user_id)
.all()
) # Results in [(001, 2)]
cooking_tasks = (
session.query(CookingTask.user_id, func.count(CookingTask.completed))
.filter(CookingTask.completed == True)
.group_by(CookingTask.user_id)
.all()
) # Results in [(001, 1), (002, 1)]
# Add some Python parsing to merge two lists of tuples into the needed format...
我尝试过并且有点效果(但不是真的):
子查询:
laundry_tasks_query = (
select([LaundryTask.user_id, func.count(LaundryTask.completed)])
.where(LaundryTask.completed == True)
.group_by(LaundryTask.user_id)
)
cooking_tasks_query = (
select([CookingTask.user_id, func.count(CookingTask.completed)])
.where(CookingTask.completed == True)
.group_by(CookingTask.user_id)
)
final_query = laundry_tasks_query.union(cooking_tasks_query).alias('completed_tasks')
completed_tasks = session.query(final_query).all()
结果:completed_tasks = [(001, 2), (001, 1), (002, 1)]
不确定是否有办法group_by
在union
查询执行之前进行,我所有的尝试都以Exception
s 结束。
我试过但没有奏效:
将所有内容都塞进一个查询中。
completed_tasks = (
session.query(
User.user_id, func.count(LaundryTask.completed), func.count(CookingTask.completed)
)
.filter(LaundryTask.completed == True)
.filter(CookingTask.completed == True)
.group_by(User.user_id)
.all()
)
我知道,天真,并且正如预期的那样,返回一些废话 aka [(001, magic_number, magic_number), (002, magic_number, magic_number), (003, magic_number, magic_number), (004, magic_number, magic_number)]
,其中magic_number
是相同的整数。
如果有任何其他方法可以实现我需要的输出,我非常愿意接受建议。任何帮助表示赞赏。
解决方案
推荐阅读
- android - Google App Store:如何测试订阅?
- ruby-on-rails - 渲染静态页面时 Rails 路由冲突
- python - 为什么 [None] * 10 比 [None for i in range(10)] 快
- javascript - reactjs props VS state:未正确设置状态
- python - 用两个不同的变量填充二维列表
- chisel - 官方皮棉方式
- python-2.7 - 所有输入数组 (x) 应具有相同数量的样本。得到数组形状:[(52, 224, 224, 3), (64, 35)]
- python - 如何修改张量值?
- mongodb - 升级到 Ubuntu 18.04 后 Mongod 升级错误
- javascript - v-for 用于作为 props 传递的数组抛出错误