代码之家  ›  专栏  ›  技术社区  ›  AnApprentice

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

  •  1
  • AnApprentice  · 技术社区  · 6 年前

    我正在创建一个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;
    
    2 回复  |  直到 6 年前
        1
  •  1
  •   Salman Arshad    6 年前

    排除 当前行。我想你可以把这个 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
    

    Fiddle

        2
  •  1
  •   D-Shih    6 年前

    你不能使用 lag 包含 COUNT

    您可以尝试使用子查询来创建它。

    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