1

I am attempting to run a query like this:

SELECT 
    comment_type_id, name, count(comment_type_id) 
FROM
    comments, commenttypes
WHERE 
    comment_type_id=commenttypes.id
GROUP BY 
    comment_type_id

Without the join between comments and commenttypes for the name column, I can do this using:

session.query(Comment.comment_type_id,func.count(Comment.comment_type_id)).group_by(Comment.comment_type_id).all()  

However, if I try to do something like this, I get incorrect results:

session.query(Comment.comment_type_id, Comment.comment_type, func.count(Comment.comment_type_id)).group_by(Comment.comment_type_id).all() 

I have two problems with the results:

(1, False, 82920)
(2, False, 588)
(3, False, 4278)
(4, False, 104370)

Problems:

  • The False is not correct
  • The counts are wrong

My expected results are:

(1, 'Comment Type 1', 13820)
(2, 'Comment Type 2', 98)
(3, 'Comment Type 2', 713)
(4, 'Comment Type 2', 17395)

How can I adjust my command to pull the correct name value and the correct count?

My model definitions look like this:

class Comment(db.Model):
    __tablename__ = 'comments'
    id = Column(Integer, primary_key=True, unique=True)
    comment_type_id = Column(Integer, ForeignKey('commenttypes.id'), nullable=False, index=True)
    comment_type = relationship('CommentType', backref='comments')

class CommentType(db.Model):
    __tablename__ = 'commenttypes'
    id = Column(Integer, primary_key=True, unique=True)
    name = Column(String(50, convert_unicode=True), nullable=False)

2 Answers 2

2

Below should do it. You need to join two models as well as add all non-aggregate columns to a group_by clause (I know it is not strictly required for all RDBMS, but i prefer to be safe)

qry = (session.query(CommentType.id, CommentType.name,
            func.count(CommentType.id).label('cnt'))
        .select_from(CommentType).join(Comment)
        .group_by(CommentType.id, CommentType.name)
        )
Sign up to request clarification or add additional context in comments.

Comments

1

First calculate the counts in a subquery, then join on that in the final query.

# calculate the comment counts for each type in a subquery
sub = session.query(
    CommentType.id,
    func.count(Comment.id).label('count')
).join(CommentType.comments
).group_by(CommentType.id
).subquery()

# select types and counts by joining on subquery
types = session.query(CommentType, sub.c.count
).join((sub, sub.c.id == CommentType.id)
).all()

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.