> -----Original Message----- > From: sqlalchemy@googlegroups.com > [mailto:[EMAIL PROTECTED] On Behalf Of John Hunter > Sent: 08 November 2008 05:09 > To: sqlalchemy@googlegroups.com > Subject: [sqlalchemy] Re: select where field=max(field) >
[SNIP] > Here is a query that lists the sum(pnl) for each symbol and strategy > in my snapshots table > > session.query(Snapshot.strategy, Snapshot.symbol, > func.sum(Snapshot.pnl)).group_by(Snapshot.strategy, > Snapshot.symbol).all() > > That works fine. But what if I only want to list the rows where the > sum(pnl)<-15000 ? I tried a few things: > > session.query(Snapshot.strategy, Snapshot.symbol, > func.sum(Snapshot.pnl)).group_by(Snapshot.strategy, > Snapshot.symbol).filter(func.sum(Snapshot.pnl)<-15000).all() > > but got the error below > > raise exc.DBAPIError.instance(statement, parameters, e, > connection_invalidated=is_disconnect) > ProgrammingError: (ProgrammingError) (1111, 'Invalid use of group > function') u'SELECT snapshot.strategy AS snapshot_strategy, > snapshot.symbol AS snapshot_symbol, sum(snapshot.pnl) AS sum_1 \nFROM > snapshot \nWHERE sum(snapshot.pnl) < %s GROUP BY snapshot.strategy, > snapshot.symbol' [-15000] > I'm no SQL expert, so please take this with a pinch of salt, but as far as I know, conditions in the 'WHERE' clause of an SQL statement are applied BEFORE any grouping, so you can't use grouping functions (such as SUM, MAX etc) in the WHERE clause. Instead, you add a 'HAVING' statement on the end to filter the rows AFTER the grouping. ie. The SQL you want is something like: SELECT snapshot.strategy AS snapshot_strategy, snapshot.symbol AS snapshot_symbol, sum(snapshot.pnl) AS sum_1 FROM snapshot GROUP BY snapshot.strategy, snapshot.symbol HAVING sum(snapshot.pnl) < 15000 In SA, I think you might be able to write that as (untested): session.query(Snapshot.strategy, Snapshot.symbol, func.sum(Snapshot.pnl)) .group_by(Snapshot.strategy, Snapshot.symbol) .having(func.sum(Snapshot.pnl)<-15000).all() BTW, I think the 'no grouping functions in WHERE clause' rule is also the reason why your MAX query didn't work. The fix that Mike gave you turned that part of your query into a subquery that only produced that single value. This statement: func.max(Snapshot.datetime).select() ...gets turned into something like 'SELECT max(datetime) FROM snapshot'. This then gets embedded as a subquery into your larger query. It's probably worth printing the SQL produced by each of the queries so that you can see the difference. Hope that helps, Simon --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "sqlalchemy" group. To post to this group, send email to sqlalchemy@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/sqlalchemy?hl=en -~----------~----~----~----~------~----~------~--~---