Reputation: 61
My Table:
tb{
caller:string
callee:string
success:boolean
time: datetime
}
This table is a call state table, every time after a function calls another one, the caller stores its own name, the function it called, the call state (success or failure) and the call time in my database.
Now I want to get results with SQL or Flask-SQLAlchemy as follows:
result(caller,callee, success_count, total_count, success_ratio)
I want to get the statistics of success_count, total_count and success_ratio grouped by every tuple (caller, callee) and ordered by success_ratio.
How can I do this with an SQL statement or Flask-SQLAlchemy?
Upvotes: 3
Views: 2157
Reputation: 773
Let's consider the following example callstate
table.
+-----------+---------------+----------+---------------------+
| caller | callee | success | time |
+-----------+---------------+----------+---------------------+
| Bar::baz | Dolor::sit | 0 | 2016-01-07 00:00:00 |
| Bar::baz | Dolor::sit | 0 | 2016-01-05 00:00:00 |
| Bar::baz | Lorem::ipsum | 0 | 2016-01-01 00:00:00 |
| Bar::baz | Lorem::ipsum | 1 | 2016-01-04 00:00:00 |
| Bar::baz | Lorem::ipsum | 1 | 2016-01-09 00:00:00 |
| Bar::baz | Lorem::ipsum | 1 | 2016-01-08 00:00:00 |
| Bar::baz | Lorem::ipsum | 1 | 2016-01-04 00:00:00 |
| Bar::baz | Qux::foo | 0 | 2016-01-05 00:00:00 |
| Bar::baz | Qux::foo | 0 | 2016-01-01 00:00:00 |
| Bar::baz | Qux::foo | 1 | 2016-01-05 00:00:00 |
| Foo::bar | Dolor::sit | 0 | 2016-01-06 00:00:00 |
| Foo::bar | Lorem::ipsum | 0 | 2016-01-08 00:00:00 |
| Foo::bar | Lorem::ipsum | 1 | 2016-01-03 00:00:00 |
| Foo::bar | Lorem::ipsum | 1 | 2016-01-05 00:00:00 |
| Foo::bar | Lorem::ipsum | 1 | 2016-01-07 00:00:00 |
| Foo::bar | Qux::foo | 0 | 2016-01-07 00:00:00 |
| Foo::bar | Qux::foo | 0 | 2016-01-04 00:00:00 |
+-----------+---------------+----------+---------------------+
A simple SQL query for getting the statistics.
SELECT caller,
callee,
sum(success) AS 'success_count',
count(*) AS 'total_count',
sum(success) / count(*) AS 'success_ratio'
FROM callstate
GROUP BY caller, callee
ORDER BY success_ratio DESC
A similar query in SQLAlchemy. For the sake of example, this is pure SQLAlchemy
, but the query part should be very similar in case of Flask-SQLAlchemy
.
#!/usr/bin/env python
from sqlalchemy import *
from sqlalchemy.orm import sessionmaker
engine = create_engine('mysql+mysqldb://johndoe@localhost:3306/so_callstate')
connection = engine.connect()
Session = sessionmaker(bind=engine)
session = Session()
cs = Table('callstate', MetaData(),
Column('caller', String()),
Column('callee', String()),
Column('success', Boolean())
)
result = session.query(
cs.c.caller,
cs.c.callee,
func.sum(cast(cs.c.success, Integer).label('success_count'),
func.count().label('total_count'),
(func.sum(cast(cs.c.success, Integer)) / func.count()).label('success_ratio')
).group_by(cs.c.caller, cs.c.callee).order_by(desc('success_ratio'))
for row in result:
print(row)
A sample output based on the example above.
('Bar::baz', 'Lorem::ipsum', Decimal('4'), 5L, Decimal('0.8000'))
('Foo::bar', 'Lorem::ipsum', Decimal('3'), 4L, Decimal('0.7500'))
('Bar::baz', 'Qux::foo', Decimal('1'), 3L, Decimal('0.3333'))
('Foo::bar', 'Qux::foo', Decimal('0'), 2L, Decimal('0.0000'))
('Bar::baz', 'Dolor::sit', Decimal('0'), 2L, Decimal('0.0000'))
('Foo::bar', 'Dolor::sit', Decimal('0'), 1L, Decimal('0.0000'))
Upvotes: 3