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

如何计算MySQL中每个组的运行和

  •  0
  • Tanzeel  · 技术社区  · 5 年前

    sum() 功能。但我的情况不同。我有一张桌子 学生

    CREATE TABLE student
        (`dateOfExam` date, score int)
    ;
        
    INSERT INTO student
        (`dateOfExam`, `score`)
    VALUES
        ('2020-05-28',5),
        ('2020-05-29',5),
        ('2020-05-30',10),
        ('2020-06-03',10),
        ('2020-06-05',5),
        ('2020-07-21',20),
        ('2020-07-22',10),
        ('2020-07-28',10)
    ;
    

    分数 对于在运行时(即举行考试的月份)中有一个以上列的考试日期:

    查询是(昨天从stackoverflow获得帮助):

    select date_format(dateOfExam, '%Y-%m') ExamMonth
         , dateOfExam
         , score 
      from student;
    

    结果:

    +-----------+------------+-------+
    | ExamMonth | dateOfExam | score |
    +-----------+------------+-------+
    | 2020-05   | 2020-05-28 |     5 |
    | 2020-05   | 2020-05-29 |     5 |
    | 2020-05   | 2020-05-30 |    10 |
    | 2020-06   | 2020-06-03 |    10 |
    | 2020-06   | 2020-06-05 |     5 |
    | 2020-07   | 2020-07-21 |    20 |
    | 2020-07   | 2020-07-22 |    10 |
    | 2020-07   | 2020-07-28 |    10 |
    +-----------+------------+-------+
    

    我的要求是每个月奖励这个学生。我会继续为每个月的每个日期添加他的分数,并给他 奖励1 累计得分达到10分时 奖励2 累计得分达到20分。最后一张表应该是这样的:

    +---------------+---------------+-------+---------------+---------------+
    | ExamMonth     |  dateOfExam   | Score |    Reward1    |   Reward2     |
    +---------------+---------------+-------+---------------+---------------+
    |    2020-05    |  2020-05-28   |   5   |               |               |
    |               |  2020-05-29   |   5   |       Y       |               |
    |               |  2020-05-30   |   10  |               |       Y       |
    |---------------|---------------|-------|---------------|---------------|
    |    2020-06    |  2020-06-03   |   10  |       Y       |               |
    |               |  2020-06-05   |   5   |               |               |
    |---------------|---------------|-------|---------------|---------------|
    |    2020-7     |  2020-07-21   |   20  |       Y       |       Y       |
    |               |  2020-07-22   |   10  |               |               |
    |               |  2020-07-28   |   10  |               |               |
    +---------------+---------------+-------+---------------+---------------+
    

    奖励字段可以是布尔值,空奖励行可以设置为N或False或任何看起来合乎逻辑的值。 Calculate running sum

    请帮我实现这个目标。建议一些方法。

    这是一个 fiddle .

    0 回复  |  直到 5 年前
        1
  •  1
  •   forpas    5 年前

    首先计算CTE中每个月的分数总和。
    然后应用您的条件:

    with cte as (
      select date_format(dateOfExam, '%Y-%m') ExamMonth,
             dateOfExam, score, 
             sum(score) over (partition by date_format(dateOfExam, '%Y-%m') order by dateOfExam) total
      from student
    )
    select ExamMonth, dateOfExam, score, 
           case when sum(total >= 10) over (partition by ExamMonth order by dateOfExam) = 1 then 'Y' end Reward1,
           case when sum(total >= 20) over (partition by ExamMonth order by dateOfExam) = 1 then 'Y' end Reward2
    from cte
    

    demo
    结果:

    > ExamMonth | dateOfExam | score | Reward1 | Reward2
    > :-------- | :--------- | ----: | :------ | :------
    > 2020-05   | 2020-05-28 |     5 | null    | null   
    > 2020-05   | 2020-05-29 |     5 | Y       | null   
    > 2020-05   | 2020-05-30 |    10 | null    | Y      
    > 2020-06   | 2020-06-03 |    10 | Y       | null   
    > 2020-06   | 2020-06-05 |     5 | null    | null   
    > 2020-07   | 2020-07-21 |    20 | Y       | Y      
    > 2020-07   | 2020-07-22 |    10 | null    | null   
    > 2020-07   | 2020-07-28 |    10 | null    | null 
    
        2
  •  1
  •   Ed Bighands    5 年前

    下面的代码段按ExamMonth上的基查询分组,然后在决定Reward1和Reward2的值时使用case。此查询仅提供指针。请重写最适合你的。

    
    select DERIVED2.ExamMonth, CASE WHEN DERIVED2.Cumul_Score >= 10 THEN 'Y'
    
    ELSE ''
    END AS Rewards1,
    CASE WHEN DERIVED2.Cumul_Score >= 20 THEN 'Y'
    
    ELSE ''
    END AS Rewards2
    FROM 
    (
    select DERIVED1.ExamMonth, SUM(DERIVED1.score) as Cumul_Score 
    FROM
    (
    select date_format(dateOfExam, '%Y-%m') ExamMonth,
           dateOfExam, score
    from student
    order by dateOfExam
    ) DERIVED1
    
    GROUP BY ExamMonth
    
    ) DERIVED2