在列 "table.id" 中使用 'over' 函数结果必须出现在 GROUP BY 子句中或在聚合函数中使用

Using 'over' function results in column "table.id" must appear in the GROUP BY clause or be used in an aggregate function

我目前正在编写一个应用程序,它显示我 table 中的事件总数随时间的增长,我目前有以下查询来执行此操作:

query = session.query(
    count(Event.id).label('count'),
    extract('year', Event.date).label('year'),
    extract('month', Event.date).label('month')
).filter(
    Event.date.isnot(None)
).group_by('year', 'month').all()

这导致以下输出:

Count Year Month
100 2021 1
50 2021 2
75 2021 3

虽然这本身没问题,但我希望它显示随时间变化的总数,而不仅仅是当月的事件数,因此所需的输出应该是:

Count Year Month
100 2021 1
150 2021 2
225 2021 3

我在很多地方读到我应该使用 SqlAlchemy 的 over 函数使用 window 函数,但是我似乎无法理解它,每次我尝试使用它时我都会得到以下错误:

sqlalchemy.exc.ProgrammingError: (psycopg2.errors.GroupingError) column "event.id" must appear in the GROUP BY clause or be used in an aggregate function
LINE 1: SELECT count(event.id) OVER (PARTITION BY event.date ORDER...
                     ^
[SQL: SELECT count(event.id) OVER (PARTITION BY event.date ORDER BY EXTRACT(year FROM event.date), EXTRACT(month FROM event.date)) AS count, EXTRACT(year FROM event.date) AS year, EXTRACT(month FROM event.date) AS month 
FROM event 
WHERE event.date IS NOT NULL GROUP BY year, month]

这是我使用的查询:

session.query(
    count(Event.id).over(
        order_by=(
            extract('year', Event.date),
            extract('month', Event.date)
        ),
        partition_by=Event.date
    ).label('count'),
    extract('year', Event.date).label('year'),
    extract('month', Event.date).label('month')
).filter(
    Event.date.isnot(None)
).group_by('year', 'month').all()

有人可以告诉我我做错了什么吗?我一直在搜索几个小时,但无法弄清楚如何获得所需的输出,因为在分组依据中添加 event.id 会阻止我的行按月和年

分组

我最终使用的最终查询:

query = session.query(
    extract('year', Event.date).label('year'),
    extract('month', Event.date).label('month'),
    func.sum(func.count(Event.id)).over(order_by=(
        extract('year', Event.date),
        extract('month', Event.date)
    )).label('count'),
).filter(
    Event.date.isnot(None)
).group_by('year', 'month')

我不是 100% 确定您想要什么,但我假设您想要每个月到该月为止的事件数。您首先需要计算每月的事件数,并将它们与 postgresql window function.

相加

您可以在一个 select 语句中做到这一点:

SELECT extract(year FROM events.date) AS year
  , extract(month FROM events.date) AS month
  , SUM(COUNT(events.id)) OVER(ORDER BY extract(year FROM events.date), extract(month FROM events.date)) AS total_so_far
FROM events
GROUP BY 1,2

但如果将其拆分为两个可能更容易考虑:

SELECT year, month, SUM(events_count) OVER(ORDER BY year, month)
FROM (
  SELECT extract(year FROM events.date) AS year
    , extract(month FROM events.date) AS month
    , COUNT(events.id) AS events_count
  FROM events
  GROUP BY 1,2
)

但不确定如何在 SqlAlchemy 中做到这一点