我有以下型号:
我需要使用SQLAlchemy orm生成以下查询:
SELECT
Album.name,
(
SELECT COUNT(*) as total_count
FROM Track
WHERE Track.album_id = Album.id
) as tracks
FROM
Album
WHERE
Album.band = ‘Metallica’ AND
tracks.total_count > 10
到目前为止的代码:
tracks = session \
.query(func.count('*').label('total_count')) \
.select_from(Track) \
.filter(Track.album_id == Album.id) \
.subquery()
query = session \
.query(Album.name, tracks.c.total_count) \
.filter(Album.band == 'Metallica') \
.filter(tracks.c.total_count > 10)
,生成的查询如下:
SELECT
Album.name,
anon_1.total_count
FROM
Album,
(
SELECT count('*') AS total_count
FROM Track, Album
WHERE Track.album_id = Album.id
) AS anon_1
WHERE
Album.band = ‘Metallica’ AND
anon_1.total_count > 10
这要慢得多。有什么想法我可以作为根选择的一部分返回子选择的结果吗?谢谢!
答案 0 :(得分:1)
您无法执行所需的查询,因为您无法在WHERE子句谓词中使用选择列表项,因为WHERE在SELECT之前进行求值。在这种情况下,普通的JOIN,GROUP BY和HAVING就足够了:
query = session \
.query(Album.name, func.count()) \
.join(Track) \
.filter(Album.band == 'Metallica') \
.group_by(Album.id) \
.having(func.count() > 10)
上面的查询使用的事实是,即使GROUP BY中未使用Album.name
,也应选择Album.id
,因为它在功能上依赖于private String courses;
。当然,鉴于没有相册共享名称,您也可以按名称分组。
您最初的尝试很慢,因为它没有在关联的子查询中执行专辑和曲目之间的子查询中的SQL-92风格的联接,有效地计数了所有曲目,并再次在专辑和封闭查询中的派生表之间进行了联接。