Reputation: 119
So this is probably a simple question but given a table that looks like
A | B | C
2020 | 1 | apple
2020 | 1 | pear
2020 | 1 | banana
2020 | 2 | apple
2020 | 2 | pear
2020 | 3 | apple
2020 | 3 | banana
And I want the last A, B
combo that has both apple
and pear
in C
How do I do have a command in sqlalchemy s.t. it would return (2020, 2)
So I have
from sqlalchemy import func
from sqlalchemy.sql import desc
result = session.\
query(table.A, table.B).\
order_by(desc(table.A)).\
order_by(desc(table.B)).\
groupby(table.A, table.B).\
having(func.count() == 2).\
first()
But I need the logic of having
to instead parse through column C
and find the first guy that has both apple
and pear
Upvotes: 0
Views: 102
Reputation: 76992
In case there is no uniqueness across the 3 columns (for example, there can be 2 rows with (2020, 2, 'pear')), the below will still provide the solution which also works with any number of criterias:
c_list = ["apple", "pear"]
subq_list = [
session.query(table.A, table.B)
.filter(table.C == c_item)
.distinct()
.subquery()
for c_item in c_list
]
# compose the query from the parts
s1, *s_rest = subq_list
stmt = select(s1).order_by(s1.c.A.desc(), s1.c.B.desc()).limit(1)
for s2 in s_rest:
stmt = stmt.join(s2, and_(s1.c.A == s2.c.A, s1.c.B == s2.c.B))
for x in session.execute(stmt):
print(x)
Upvotes: 1
Reputation: 119
Wow sorry, I figured it out really quickly after
from sqlalchemy import func
from sqlalchemy.sql import desc
c_list = ['apple', 'pear']
result = session.\
query(table.A, table.B).\
filter(table.C.in_(c_list)).\
order_by(desc(table.A)).\
order_by(desc(table.B)).\
groupby(table.A, table.B).\
having(func.count() == len(c_list)).\
first()
The only problem is that, this assumes that all combinations of A, B, and C are distinct. Not sure how to get around that...
Upvotes: 0