From: Mike Bayer Date: Fri, 11 Aug 2006 21:43:55 +0000 (+0000) Subject: SelectResults will use a subselect, when calling an aggregate (i.e. X-Git-Tag: rel_0_2_7~16 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=c48727aeed66ae94d66b79790e841223c45f1a51;p=thirdparty%2Fsqlalchemy%2Fsqlalchemy.git SelectResults will use a subselect, when calling an aggregate (i.e. max, min, etc.) on a SelectResults that has an ORDER BY clause [ticket:252] --- diff --git a/CHANGES b/CHANGES index 3628b70c23..450af4d585 100644 --- a/CHANGES +++ b/CHANGES @@ -34,6 +34,9 @@ return an array instead of string for SHOW CREATE TABLE call - inheritance check uses issubclass() instead of direct __mro__ check to make sure class A inherits from B, allowing mapper inheritance to more flexibly correspond to class inheritance [ticket:271] +- SelectResults will use a subselect, when calling an aggregate (i.e. +max, min, etc.) on a SelectResults that has an ORDER BY clause +[ticket:252] 0.2.6 - big overhaul to schema to allow truly composite primary and foreign diff --git a/lib/sqlalchemy/ext/selectresults.py b/lib/sqlalchemy/ext/selectresults.py index 2ad52c8f0a..79d56ec675 100644 --- a/lib/sqlalchemy/ext/selectresults.py +++ b/lib/sqlalchemy/ext/selectresults.py @@ -29,22 +29,34 @@ class SelectResults(object): def count(self): """executes the SQL count() function against the SelectResults criterion.""" return self._query.count(self._clause) - + + def _col_aggregate(self, col, func): + """executes func() function against the given column + + For performance, only use subselect if order_by attribute is set. + + """ + if self._ops.get('order_by'): + s1 = sql.select([col], self._clause, **self._ops).alias('u') + return sql.select([func(s1.corresponding_column(col))]).scalar() + else: + return sql.select([func(col)], self._clause, **self._ops).scalar() + def min(self, col): """executes the SQL min() function against the given column""" - return sql.select([sql.func.min(col)], self._clause, **self._ops).scalar() + return self._col_aggregate(col, sql.func.min) def max(self, col): """executes the SQL max() function against the given column""" - return sql.select([sql.func.max(col)], self._clause, **self._ops).scalar() + return self._col_aggregate(col, sql.func.max) def sum(self, col): """executes the SQL sum() function against the given column""" - return sql.select([sql.func.sum(col)], self._clause, **self._ops).scalar() + return self._col_aggregate(col, sql.func.sum) def avg(self, col): """executes the SQL avg() function against the given column""" - return sql.select([sql.func.avg(col)], self._clause, **self._ops).scalar() + return self._col_aggregate(col, sql.func.avg) def clone(self): """creates a copy of this SelectResults."""