zoukankan      html  css  js  c++  java
  • 在拉链表中取用户每个月最后一天的状态

    with data as (
        select 
            t1.*
            ,row_number() over(partition by id order by end_date desc) as rn
        from (
            select 1 as id,20 as status,'2020-03-28' as start_date,'2020-04-05' as end_date union all
            select 1 as id,10 as status,'2020-04-05' as start_date,'2020-04-20' as end_date union all
            select 1 as id,30 as status,'2020-04-21' as start_date,'2020-05-02' as end_date union all
            select 2 as id,20 as status,'2020-01-28' as start_date,'2020-04-05' as end_date
        ) t1
    ) -- 1. 测试数据
    -- select * from data;
    ,cal as (
        select 
            month
            ,last_day(month) as month_last_day
            ,date_add(month, interval - day(month) + 1 day) as month_first_day
        from (
            select '2020-01-01' as month union all
            select '2020-02-01' as month union all
            select '2020-03-01' as month union all
            select '2020-04-01' as month union all
            select '2020-05-01' as month union all
            select '2020-06-01' as month union all
            select '2020-07-01' as month union all
            select '2020-08-01' as month union all
            select '2020-09-01' as month union all
            select '2020-10-01' as month union all
            select '2020-11-01' as month union all
            select '2020-12-01' as month
        ) t1
    ) -- 2. 日历
    -- select * from cal;
    ,id_max_day as (
        select 
             id
            ,min(start_date) as start_date
            ,max(end_date) as end_date
        from data
        group by 
            id
    ) -- 3. 取出id的最大值和最小值
    -- select * from id_max_day;
    ,id_month as (
        select
            t1.*,t2.month,t2.month_last_day,t2.month_first_day
        from id_max_day t1
        inner join cal t2
            on 1 = 1
        where t2.month >= DATE_ADD(t1.start_date,interval -day(t1.start_date)+1 day) -- 开始时间的当月第一天
            and t2.month <=  t1.end_date
    ) -- 4. 获取所有id的取数范围
    -- select * from id_month order by id,month;
    select
        -- t1.*,t2.*
         t1.id
        ,t1.status
        ,t2.month
    from data t1
    inner join id_month t2
        on t1.id = t2.id
    where t1.start_date <= t2.month_last_day
        and 
            case 
            when t1.rn = 1 then last_day(t1.end_date) >= t2.month_last_day
            else t1.end_date >= t2.month_last_day
            end
    order by t1.id,t2.month 
    ;
    
    +----+--------+------------+------------+----+------------+------------+------------+----------------+-----------------+
    | id | status | start_date | end_date   | id | start_date | end_date   | month      | month_last_day | month_first_day |
    +----+--------+------------+------------+----+------------+------------+------------+----------------+-----------------+
    |  1 |     20 | 2020-03-28 | 2020-04-05 |  1 | 2020-03-28 | 2020-05-02 | 2020-03-01 | 2020-03-31     | 2020-03-01      |
    |  1 |     30 | 2020-04-21 | 2020-05-02 |  1 | 2020-03-28 | 2020-05-02 | 2020-04-01 | 2020-04-30     | 2020-04-01      |
    |  2 |     20 | 2020-01-28 | 2020-04-05 |  2 | 2020-01-28 | 2020-04-05 | 2020-01-01 | 2020-01-31     | 2020-01-01      |
    |  2 |     20 | 2020-01-28 | 2020-04-05 |  2 | 2020-01-28 | 2020-04-05 | 2020-02-01 | 2020-02-29     | 2020-02-01      |
    |  2 |     20 | 2020-01-28 | 2020-04-05 |  2 | 2020-01-28 | 2020-04-05 | 2020-03-01 | 2020-03-31     | 2020-03-01      |
    +----+--------+------------+------------+----+------------+------------+------------+----------------+-----------------+
    
    -- 1. 测试数据
    +----+--------+------------+------------+
    | id | status | start_date | end_date   |
    +----+--------+------------+------------+
    |  1 |     20 | 2020-03-28 | 2020-04-05 | 2020-03-01
    |  1 |     10 | 2020-04-05 | 2020-04-20 |
    |  1 |     30 | 2020-04-21 | 2020-05-02 |
    |  2 |     20 | 2020-01-28 | 2020-04-05 |
    +----+--------+------------+------------+
    
    +----+--------+------------+
    | id | status | month      |
    +----+--------+------------+
    |  1 |     20 | 2020-03-01 |
    |  1 |     30 | 2020-04-01 |
    |  1 |     30 | 2020-05-01 |
    |  2 |     20 | 2020-01-01 |
    |  2 |     20 | 2020-02-01 |
    |  2 |     20 | 2020-03-01 |
    |  2 |     20 | 2020-04-01 |
    +----+--------+------------+
    
    
    
    -- 3. 取出id的最大值和最小值
    +----+------------+------------+
    | id | start_date | end_date   |
    +----+------------+------------+
    |  1 | 2020-03-28 | 2020-05-02 |
    |  2 | 2020-01-28 | 2020-04-05 |
    +----+------------+------------+
    
    -- 4. 获取所有id的取数范围
    +----+------------+------------+------------+
    | id | start_date | end_date   | month      |
    +----+------------+------------+------------+
    |  1 | 2020-03-28 | 2020-05-02 | 2020-03-01 |
    |  1 | 2020-03-28 | 2020-05-02 | 2020-04-01 |
    |  1 | 2020-03-28 | 2020-05-02 | 2020-05-01 |
    |  2 | 2020-01-28 | 2020-04-05 | 2020-01-01 |
    |  2 | 2020-01-28 | 2020-04-05 | 2020-02-01 |
    |  2 | 2020-01-28 | 2020-04-05 | 2020-03-01 |
    |  2 | 2020-01-28 | 2020-04-05 | 2020-04-01 |
    +----+------------+------------+------------+
    
    -- 最终结果
    +----+--------+------------+------------+----+------------+------------+------------+
    | id | status | start_date | end_date   | id | start_date | end_date   | month      |
    +----+--------+------------+------------+----+------------+------------+------------+
    |  1 |     20 | 2020-03-28 | 2020-04-05 |  1 | 2020-03-28 | 2020-05-02 | 2020-04-01 |
    |  1 |     30 | 2020-04-21 | 2020-05-02 |  1 | 2020-03-28 | 2020-05-02 | 2020-05-01 |
    |  2 |     20 | 2020-01-28 | 2020-04-05 |  2 | 2020-01-28 | 2020-04-05 | 2020-02-01 |
    |  2 |     20 | 2020-01-28 | 2020-04-05 |  2 | 2020-01-28 | 2020-04-05 | 2020-03-01 |
    |  2 |     20 | 2020-01-28 | 2020-04-05 |  2 | 2020-01-28 | 2020-04-05 | 2020-04-01 |
    +----+--------+------------+------------+----+------------+------------+------------+
  • 相关阅读:
    asp.net core MVC 入门学习
    C# 中关于重载与重写的区别及用法
    C# 生成随机的6位字母,包含大小写
    C# CheckBoxList绑定值,设置及获取
    jquery中checkbox的全选与反选
    docker 执行 docker system prune 导致Azure Devops build镜像失败
    Navicat 连接mysql 报错: Authentication plugin caching_ sha2_password cannot be loaded
    docker build 错误 /usr/share/dotnet/sdk/2.1.801/Microsoft.Common.CurrentVersion.targets(2106,5): warning MSB3245: Could not resolve this reference
    Azure Devops: COPY failed: stat /var/lib/docker/tmp/docker-builder268095359/xxxxxxx.csproj no such file or directory
    Azure DevOps vsts-agent-linux 安装出错, Must not run with sudo
  • 原文地址:https://www.cnblogs.com/chenzechao/p/13044607.html
Copyright © 2011-2022 走看看