I think I'm looking for something like this: 

CREATE TABLE #B_temp(id INTEGER, A_id INTEGER, word VARCHAR, number 
INTEGER);
CREATE TABLE #C_temp(id INTEGER, A_id INTEGER, word VARCHAR, number 
INTEGER);
SELECT * FROM B WHERE id IN (SELECT MAX(id) FROM B GROUP BY A_id) INTO 
#B_temp;
SELECT * FROM C WHERE id IN (SELECT MAX(id) FROM C GROUP BY A_id) INTO 
#C_temp;
SELECT A.* , #B_temp.*, #C_temp.* FROM A LEFT OUTER JOIN #B_temp ON A.id = 
#B_temp.A_id LEFT OUTER JOIN #C_temp ON A.id = #C_temp.A_id;

but with all the nice generality that comes from sqlalchemy. 

Thanks for the quick response, 

Michael

On Tuesday, March 11, 2014 7:41:32 PM UTC-4, Michael Bayer wrote:
>
> can you express the exact query you want in SQL?   I can translate to that 
> easily if you have it.  Otherwise if you’re looking to figure out what the 
> SQL would be I’d have to find time to look more closely.
>
>
> On Mar 11, 2014, at 7:29 PM, Michael Weylandt 
> <michael....@gmail.com<javascript:>> 
> wrote:
>
> Database wizards, 
>
> I've got a situation where I have one table with multiple one-to-many 
> mappings (i.e., it is the "one" in a "one-to-many" with more than one other 
> table). 
>
> For each row of the "one", I want to group each of the "many"s by some 
> column and do an outer join between the "one" and the "group by max" rows 
> of each "many."
>
> Minimal example: 
>
>
> #################################################################################################
> from sqlalchemy import create_engine, Column, String, Integer, ForeignKey
> from sqlalchemy.orm import sessionmaker
> from sqlalchemy.ext.declarative import declarative_base
>
> engine = create_engine("sqlite:///:memory:", echo = True)
> session = sessionmaker(bind = engine)()
>
> Base = declarative_base()
>
> class A(Base):
>     __tablename__ = 'A'
>     id = Column(Integer, primary_key = True)
>     letter = Column(String)
>
>     def __repr__(self):
>         return "A(id = %s, letter = %s)" % (self.id, self.letter)
>
> class B(Base):
>     __tablename__ = 'B'
>     id = Column(Integer, primary_key = True)
>     A_id = Column(Integer, ForeignKey('A.id'), nullable = False)
>     word = Column(String)
>     number = Column(Integer)
>
>     def __repr__(self):
>         return "B(A_id = %s, word = %s, number = %s)" % (self.A_id, 
> self.word, self.number)
>
>
> class C(Base):
>     __tablename__ = 'C'
>     id = Column(Integer, primary_key = True)
>     A_id = Column(Integer, ForeignKey('A.id'), nullable = False)
>     word = Column(String)
>     number = Column(Integer)
>
>     def __repr__(self):
>         return "B(A_id = %s, word = %s, number = %s)" % (self.A_id, 
> self.word, self.number)
>
> Base.metadata.create_all(engine)
>
> session.add_all([
>     A(letter = "A", id = 1),
>     A(letter = "B", id = 2),
>     A(letter = "C", id = 3),
>     ])
> session.commit()
>
> session.add_all([
>     B(A_id = 1, word = "Foo", number = 1),
>     B(A_id = 1, word = "Bar", number = 2),
>     B(A_id = 3, word = "Baz", number = 2),
>     ])
> session.commit()
>
> session.add_all([
>     C(A_id = 1, word = "cat", number = 5),
>     C(A_id = 2, word = "dog", number = 6),
>     C(A_id = 2, word = "cow", number = 2),
>     ])
> session.commit()
>
> ## I want a query which returns
> ## A.letter | B.word | B.number | C.word | C.number
> ## ------------------------------------------------
> ## A        | Bar    | 2        | cat    | 5
> ## B        | NULL   | NULL     | dog    | 6
> ## C        | Baz    | 2        | NULL   | NULL
> ##
> ## That is, for each A
> ##   1) Group table B by A_id, and select the B in each group with the 
> highest B.number
> ##   1) Group table C by A_id, and select the C in each group with the 
> highest C.number
> ##   Returning NULL (left outer join) if nothing is found
>
>
> ################################################################################
>
> I've tried playing with subqueries and func.max and I'm able to get the 
> outer join + grouping, but I'm not getting the "max row" for each group. 
> Something like this: 
>
>
> ###################################################################################
> from sqlalchemy import func
> b_subq = session.query(func.max(B.number).label("b_max"), 
> B).group_by(B.A_id).subquery()
> c_subq = session.query(func.max(C.number).label("c_max"), 
> C).group_by(C.A_id).subquery()
>
> session.query(A, B, C).outerjoin(B, C).group_by(A).outerjoin(b_subq, 
> c_subq).all() ## Fails for some reason
> session.query(A, B, C).outerjoin(B, C).outerjoin(b_subq).group_by(A).all() 
> ## Works after removing c_subq
>
> ###################################################################################
>
> Any pointers? 
>
> Thanks, 
> Michael 
>
> (Details: python 2.7.3, sqlalchemy 0.8.1, RHEL 6)
>
> -- 
> You received this message because you are subscribed to the Google Groups 
> "sqlalchemy" group.
> To unsubscribe from this group and stop receiving emails from it, send an 
> email to sqlalchemy+...@googlegroups.com <javascript:>.
> To post to this group, send email to sqlal...@googlegroups.com<javascript:>
> .
> Visit this group at http://groups.google.com/group/sqlalchemy.
> For more options, visit https://groups.google.com/d/optout.
>
>
>

-- 
You received this message because you are subscribed to the Google Groups 
"sqlalchemy" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to sqlalchemy+unsubscr...@googlegroups.com.
To post to this group, send email to sqlalchemy@googlegroups.com.
Visit this group at http://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/d/optout.

Reply via email to