如何在sqlalchemy中获取每天的行数?

时间:2018-10-08 10:11:53

标签: python postgresql sqlalchemy

我有一个简单的表格,

ID    DateTime          Category
--  --------            ----------   
1   2018-05-12 5:05        1
2   2018-05-12 5:10        1
3   2018-05-12 6:25        2
4   2018-05-13 7:40        1
5   2018-05-14 8:50        4

我想计算每个类别每天的条目数,所以结果应该像这样

Day          Category   Count
---------    --------  -------
2018-05-12       1        2
2018-05-12       2        1
2018-05-13       1        1
2018-05-14       4        1

如何在sqlalchmey中做到这一点?

编辑:我正在使用的数据库是PostgreSQL

修改:列及其特定类型如下, ID-整数,类别-整数,DateTime-DateTime

3 个答案:

答案 0 :(得分:1)

最简单的方法是执行以下操作(不包括类别):

from sqlalchemy import text

q = text(
      """
      SELECT d.date, count(se.id)
      FROM (
        SELECT to_char(date_trunc('day', (current_date - offs)), 'YYYY-MM-DD') AS date 
        FROM generate_series(0, <NUMBER_OF_DAYS>, 1) AS offs
     ) d 
     LEFT OUTER JOIN some_table se 
       ON d.date = to_char(date_trunc('day', se.created), 'YYYY-MM-DD'))  
     GROUP BY d.date;
     """
)
session.execute(q).all()

答案 1 :(得分:0)

demo:db<>fiddle

由于我不是很喜欢SQLAlchemy,所以我可以向您展示纯粹的Postgres方法:

SELECT datetime::date, category, COUNT(*)
FROM simple_table
GROUP BY datetime::date, category

使用EXTRACThttps://www.postgresql.org/docs/current/static/functions-datetime.html),几周就可以做到这一点

WITH weeks AS (
    SELECT EXTRACT(week from datetime) as week, category FROM simple_table 
)
SELECT week, category, COUNT(*)
FROM weeks
GROUP BY week, category

答案 2 :(得分:0)

由于您没有提到计数为0的行,可能对您有帮助

def getRange(start, end, aggregate):
        query = db.select([
                func.max(Simulation.timestamp).label('timestamp'),
                func.sum(Simulation.PVPowerOutput).label('PVPowerOutput'),
                func.sum(Simulation.ACPrimaryLoad).label('ACPrimaryLoad')\
            ])\
            .where(Simulation.timestamp >= start)\
            .where(Simulation.timestamp <= end)\

        if aggregate == 'hourly':
            # do nothing
            query = query.group_by(Simulation.timestamp)
        elif aggregate == 'daily':
            # group by date
            query = query.group_by(func.date(Simulation.timestamp))
        elif aggregate == 'monthly':
            # group by month
            query = query.group_by(func.date_part('month', Simulation.timestamp))
        else:
            raise ValueError('invalid aggregation')
        return [dict(r) for r in db.session.execute(query).fetchall()]