在 sqlalchemy 中分组并计数

group by and count in sqlalchemy

我有下面的 table:

conn.execute(hotel.insert(), [
   {'country':'India', 'city' : 'Pune', 'name': 'name1'},
   {'country':'India', 'city' : 'Mumbai', 'name': 'name2'},
   {'country':'India', 'city' : 'Nagpur', 'name': 'name3'},
   {'country':'US', 'city' : 'San Jose', 'name': 'name4'},
   {'country':'US', 'city' : 'San Francisco', 'name': 'name5'},
   {'country':'US', 'city' : 'San Mateo', 'name': 'name6'},
   {'country':'Brazil', 'city' : 'abc', 'name': 'name7'},
   {'country':'Brazil', 'city' : 'pqr', 'name': 'name8'},
   {'country':'Brazil', 'city' : 'xyz', 'name': 'name9'},
   {'country':'India', 'city' : 'Pune', 'name': 'name10'},
   {'country':'India', 'city' : 'Pune', 'name': 'name11'},
   {'country':'US', 'city' : 'San Jose', 'name': 'name12'},
   {'country':'Brazil', 'city' : 'abc', 'name': 'name13'},
])

我想为每个国家找出一个条目数最多的城市。

我按照 this 示例并使用以下查询获得了此输出: 查询:

from sqlalchemy import create_engine, MetaData, Table, Column, Integer, String
from sqlalchemy import func
from sqlalchemy.orm import sessionmaker

engine = create_engine('sqlite:///hotel.db', echo = True)
meta = MetaData()

hotel = Table(
   'hotel', meta,
   Column('country', String),
   Column('city', String),
   Column('name', String),
)

Session = sessionmaker(bind = engine)
session = Session()
print(session.query(hotel.columns.city, func.count(hotel.columns.city)).group_by(hotel.columns.country).all())

输出:

[('abc', 4), ('Pune', 5), ('San Jose', 4)]

它给出了所有城市的最大条目数,但显示的计数是针对一个国家/地区的条目数?不知道 sqlalchemy 是如何工作的,如果它太天真了。

您需要使用子查询来计算每个国家/地区的城市数,并且 select 子查询的最大计数:

subq = select(hotel.c.country,
              hotel.c.city,
              func.count(hotel.c.city)
              .label('count'))\
              .group_by(hotel.c.country,
                        hotel.c.city)\
              .subquery()
stmt = select(subq.c.city,
              subq.c.count)\
              .having(func.max(subq.c.count))\
              .group_by(subq.c.country)
print(session.execute(stmt).all())