简体   繁体   中英

How to sort query by connections number

Parent and Child tables are linked with parent_uuid ForeignKey attribute:

from sqlalchemy.ext.declarative import declarative_base
import uuid

Base = declarative_base()
class Parent(Base):
    __tablename__ = 'parents'
    uuid = Column(String(64), primary_key=True, unique=True)
    def __init__(self):  
        self.uuid = uuid.uuid4()   

class Child(Base):
    __tablename__ = 'children'
    uuid = Column(String(64), primary_key=True, unique=True)
    parent_uuid = Column(String(64), ForeignKey('parents.uuid'))
    def __init__(self, parent_uuid=None):  
        self.uuid = uuid.uuid4()   
        self.parent_uuid = parent_uuid

for loop is used to declare Parent objects. And with random.randomint() ) each parent is linked random number of children:

for i in range(25):
    parent = Parent()
    session.add(parent)
    session.commit()
    parent_uuid = parent.uuid 
    for i in range(random.randint(0, 10)):
        child = Child(parent_uuid=parent_uuid)
        session.add(child)
        session.commit()

How to query all Parent entities ordering them by a number of linked Children . Parent with the highest number of children should be the first in a list. I could be sorting by uuid attribute using order_by() function:

session.query(Parent).order_by(desc(Parent.uuid)).all()

But here, the number of children needs to be calculated first. How to sort by a value that was not yet calculated?

You can use partition by, with a count function which will add the count of each of the children related to their parents. Then you can use that column to order by.

Looks like this:

from sqlalchemy import desc, func

query = session.query(Parent, Child, func.count().over(partition_by=Parent.uuid)
.label('children_count'))
.filter(Child.parent_uuid == Parent.uuid)
.order_by(desc('children_count'))
print(query)

which will produce the following sql:

SELECT parents.uuid AS parents_uuid, children.uuid AS children_uuid,
children.parent_uuid AS children_parent_uuid, 
count(*) OVER (PARTITION BY parents.uuid) AS children_count
FROM parents, children
WHERE children.parent_uuid = parents.uuid ORDER BY children_count DESC

which gives you parents and children sorted by the highest count of related children records.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM