【问题标题】:Get column value for last 3 years in single select statement (MYSQL)在单个选择语句(MYSQL)中获取最近 3 年的列值
【发布时间】:2022-01-28 00:04:15
【问题描述】:

假设我有下表:

id user_id level date_created
1 1 2 2019-07-01T18:53:41.000Z
2 1 3 2020-07-01T18:53:41.000Z
3 1 4 2021-07-01T18:53:41.000Z
4 2 2 2020-07-01T18:53:41.000Z

假设我想根据创建日期在一行中获取过去 3 年中每一年的用户 level

类似:

SELECT user_id, (some query here) AS "level_2019"
      , (some query here) AS "level_2020", (some query here) AS "level_2021"  
FROM table

这对于单个选择语句来说是可能的吗?如果他们没有那一年的级别,我也希望那一年的级别为空。

谢谢!

【问题讨论】:

    标签: mysql sql database


    【解决方案1】:

    由于动态别名,您需要 dynamuc sql 进行此类查询

    CREATE TABLE table1 (
      `id` INTEGER,
      `user_id` INTEGER,
      `level` INTEGER,
      `date_created` varchaR(24)
    );
    
    INSERT INTO table1
      (`id`, `user_id`, `level`, `date_created`)
    VALUES
      ('1', '1', '2', '2019-07-01T18:53:41.000Z'),
      ('2', '1', '3', '2020-07-01T18:53:41.000Z'),
      ('3', '1', '4', '2021-07-01T18:53:41.000Z'),
      ('4', '2', '2', '2020-07-01T18:53:41.000Z');
    
    SET @column_alias1 := CONCAT('level_',YEAR(NOW() - INTERVAL 3 Year));
    SET @column_alias2 := CONCAT('level_',YEAR(NOW() - INTERVAL 2 Year));
    SET @column_alias3 := CONCAT('level_',YEAR(NOW() - INTERVAL 1 Year));
    SET @query := CONCAT('SELECT `user_id`,
    MIN( IF (YEAR(CAST(`date_created` AS DATETIME)) = YEAR( NOW() - INTERVAL 3 YEAR), `level`,NULL)) as `', @column_alias1, '` 
    ,MIN( IF (YEAR(CAST(`date_created` AS DATETIME)) = YEAR( NOW() - INTERVAL 2 YEAR), `level`,NULL)) as `', @column_alias2, '`
    ,MIN( IF (YEAR(CAST(`date_created` AS DATETIME)) = YEAR( NOW() - INTERVAL 1 YEAR), `level`,NULL)) as `', @column_alias3, '`
    FROM table1
    GROUP BY `user_id`');
    PREPARE dynamic_statement FROM @query;
    EXECUTE dynamic_statement
    
    用户 ID | level_2019 | level_2020 | level_2021 ------: | ---------: | ---------: | ---------: 1 | 2 | 3 | 4 2 | | 2 |

    db小提琴here

    【讨论】:

    • 好的,谢谢!如果我能够使用静态别名,比如我需要的年份是 2019、2020、2021,那么如果没有动态 sql,这可以实现吗?
    • 认为我回答了我自己的问题,对不起!太棒了。谢谢。
    • 如果同一年设置了两个级别,并且我在那里使用MAX而不是MIN,它会得到当年的最高级别吗?除非我遗漏了什么,否则我会假设是的。
    • 是的,没有动态别名 ypou 不需要动态 sql。如果您有多个级别,则需要更多代码,例如行号和外部 sql
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-02-28
    • 1970-01-01
    • 2016-12-28
    • 1970-01-01
    • 2013-10-06
    • 1970-01-01
    • 2020-02-23
    相关资源
    最近更新 更多