sqlalchemy - 如何从联合查询中选择计数

时间:2016-08-04 22:22:47

标签: python sqlalchemy flask-sqlalchemy

我的目标是我有两个表,每个表描述用户与“团队”或“公司”之间的关系

如果在userid的表中有任何行显示“admin”,那么我想知道,否则如果没有行,那么我也需要知道。

到目前为止我所拥有的内容如下(UserTeamLink和UserCompanyLink)是Orm标签。

obj = UserTeamLink
q1 = session.query(func.count(obj.type).label("cnt")).filter(obj.type == 'admin').filter(obj.user_id == id) ; str(q1) ; q1.all()
obj = UserCompanyLink
q2 = session.query(func.count(obj.type).label("cnt")).filter(obj.type == 'admin').filter(obj.user_id == id) ; str(q2) ; q2.all()

my_union = q1.union_all(q2)
query = select([func.sum(my_union.c.cnt).label("total_cnt")], from_obj=my_union)
query.all()

然而,行“query = select([func.sum(my_union.c.cnt).label(”total_cnt“)],from_obj = my_union)”break with:

AttributeError: 'BaseQuery' object has no attribute 'c'

整个输出如下:

>>> obj = UserTeamLink
>>> q1 = session.query(func.count(obj.type).label("cnt")).filter(obj.type == 'admin').filter(obj.user_id == id) ; str(q1) ; q1.all()
'SELECT count(user_team.type) AS cnt \nFROM user_team \nWHERE user_team.type = :type_1 AND user_team.user_id = :user_id_1'
[(0L,)]
>>> obj = UserCompanyLink
>>> q2 = session.query(func.count(obj.type).label("cnt")).filter(obj.type == 'admin').filter(obj.user_id == id) ; str(q2) ; q2.all()
'SELECT count(user_company.type) AS cnt \nFROM user_company \nWHERE user_company.type = :type_1 AND user_company.user_id = :user_id_1'
[(0L,)]
>>> 
>>> my_union = q1.union_all(q2)
>>> query = select([func.sum(my_union.c.cnt).label("total_cnt")], from_obj=my_union)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'BaseQuery' object has no attribute 'c'

有没有办法解决这个问题?

总之,我正在尝试做的是从两个表中选择计数,然后将union连接到另一个表中,然后添加它们。

谢谢。

2 个答案:

答案 0 :(得分:0)

您需要使用my_union作为子查询

my_union = q1.union_all(q2).subquery()
query = select([func.sum(my_union.c.cnt).label("total_cnt")], from_obj=my_union)

答案 1 :(得分:0)

这是我自己的问题解决了,我使用了与@ r-m-n略有不同的方法,但我认为两者都应该有效:

    q_union = q1.union_all(q2)
    q_union_cnt = db.session.query(func.sum(q_union.subquery().columns.cnt).label("total_cnt"))
    admin_points = q_union_cnt.scalar()