mysql错误1111-嵌套窗口函数时组函数的使用无效

o2rvlv0m  于 2021-06-19  发布在  Mysql
关注(0)|答案(2)|浏览(406)

我正在创建一个sql报表 answers 表格:

id | created_at
1  | 2018-03-02 18:05:56
2  | 2018-04-02 18:05:56
3  | 2018-04-02 18:05:56
4  | 2018-05-02 18:05:56
5  | 2018-06-02 18:05:56

输出为:

weeks_ago | record_count (# of rows per weekly cohort) | growth (%)
-4        | 21                                         |  22%
-3        | 22                                         | -12%
-2        | 32                                         |   2%
-1        |  2                                         |  20%
 0        | 31                                         |   0%

我的查询当前出错:

1111 - Invalid use of group function

我做错什么了?

SELECT  floor(datediff(f.created_at, curdate()) / 7) AS weeks_ago,
                count(DISTINCT f.id) AS "New Records in Cohort",
                100 * (count(*) - lag(count(*), 1) over (order by f.created_at)) / lag(count(*), 1) over (order by f.created_at) || '%' as growth
FROM answers f
WHERE f.completed_at IS NOT NULL
GROUP BY weeks_ago
HAVING count(*) > 1;
p1iqtdky

p1iqtdky1#

你不能使用 lag 包含 COUNT aggregate函数,因为使用aggregate function contain aggregate函数时它无效。
您可以尝试使用子查询来创建它。

SELECT weeks_ago,
       NewRecords "New Records in Cohort",
      100 * (cnt - lag(cnt, 1) over (order by created_at)) / lag(cnt, 1) over (order by created_at) || '%' as growth
FROM (
    SELECT floor(datediff(f.created_at, curdate()) / 7) AS weeks_ago, 
           COUNT(*) over(partition by weeks_ago order by weeks_ago) cnt,
           count(DISTINCT f.id) NewRecords,
           f.created_at
    FROM answers f
) t1
wr98u20j

wr98u20j2#

我想您需要查找除当前行以外的所有行的运行计数。我想你可以把这个 LAG 功能如下:

SELECT
    COUNT(*) OVER (ORDER BY f.created_at ROWS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING) x, -- running count before current row
    COUNT(*) OVER (ORDER BY f.created_at) y -- running count including current row

你可以随心所欲地除法和乘法。
不。你只需要分开 GROUP BY 以及 LAG OVER :

WITH cte AS (
    SELECT
        FLOOR(DATEDIFF(created_at, CURDATE()) / 7) AS weeks_ago,
        COUNT(DISTINCT id) AS new_records
    FROM answers
    WHERE 1 = 1 -- todo: change this
    GROUP BY weeks_ago
    HAVING 1 = 1 -- todo: change this
)
SELECT
    cte.*,
    100 * (
        new_records - LAG(new_records) OVER (ORDER BY weeks_ago)
    ) / LAG(new_records) OVER (ORDER BY weeks_ago) AS percent_increase
FROM cte

小提琴

相关问题