• 一个时间段2条记录如何把时间段内所有日期构造出来


     代码问题与答案均来自sql server数据库技术群

    问题来自 群内time,答案来自群内上海-小刀

    需求

      

    测试代码

    SELECT * FROM (
    SELECT '2019-01-03' AS FDATE,'职员'  FJOB,'123' FCODE
    UNION 
    SELECT '2019-01-07','经理', '123'
    UNION 
    SELECT '2019-01-03','职员', '466'
    UNION 
    SELECT '2019-01-05','主管', '466'
    UNION 
    SELECT '2019-01-07','副经理', '466') b
    ORDER BY fcode,b.FDATE
    
    SELECT * FROM (SELECT '2019-01-03' AS FDATE,'职员' FJOB ,'123' AS FCODE
    UNION 
    SELECT '2019-01-04','职员','123'
    UNION 
    SELECT '2019-01-05','职员','123'
    UNION 
    SELECT '2019-01-06','职员','123'
    UNION 
    SELECT '2019-01-07','经理','123'
    UNION 
    SELECT '2019-01-03','职员','466'
    UNION 
    SELECT '2019-01-04','职员','466'
    UNION 
    SELECT '2019-01-05','主管','466'
    UNION 
    SELECT '2019-01-06','主管','466'
    UNION 
    SELECT '2019-01-07','副经理','466') A
    ORDER BY FCODE,FDATE

    2012之前解法

    if OBJECT_ID('tempdb.dbo.#t','u') is not null drop table #t
    go
    create table #t(fdate date,fjob nvarchar(10),fcode int)
    go
    insert #t select '2019-01-03','职员',123
    insert #t select '2019-01-07','经理',123
    insert #t select '2019-01-03','职员',456
    insert #t select '2019-01-05','主管',456
    insert #t select '2019-01-07','副经理',456
    go
    select * from #t
    go
    ;with 
      t1 as (select rid=ROW_NUMBER()over(partition by fcode order by fdate),* from #t)
      ,t2 as(select a.*,dt=isnull(datediff(d,a.fdate ,b.fdate),1) from t1 a left join t1 b on a.fcode =b.fcode and a.rid =b.rid -1)
    select 
        fdate=dateadd(d,t3.number,t2.fdate)
        ,t2.fjob
        ,t2.fcode    
    from t2 
    join
    (select number from master.dbo.spt_values s where s.type ='p')t3
    on t3.number<t2.dt

    2012之后解法

    --sql2012+ 写法
    
    ;with 
      t2 as (select #t.*,dt=isnull(datediff(d,fdate,lead(fdate,1,null)over(partition by fcode order by fdate)),1) from #t)
    select 
        fdate=dateadd(d,t3.number,t2.fdate)
        ,t2.fjob
        ,t2.fcode    
    from t2 
    join
    (select number from master.dbo.spt_values s where s.type ='p')t3
    on t3.number<t2.dt

    常规写法:

    create table #temp(fdate datetime, fjob varchar(32), fcode int);
    
    insert into #temp values
    ('2019/01/03','职员',123),
    ('2019/01/07','主管',123),
    ('2019/01/03','职员',456),
    ('2019/01/05','主管',456),
    ('2019/01/07','副经理',456);
    
    select fcode,fdate,fjob from (
    select r.fcode,r.fdate,t.fjob,row_number() over(partition by r.fcode,r.fdate order by t.fdate desc) as rank from (
    select fcode,min(fdate) as a,max(fdate) as b from #temp group by fcode
    ) as s
    cross apply (
    select s.fcode,dateadd(day,number,s.a) as fdate from master..spt_values where type='P' and dateadd(day,number,s.a)<=s.b
    ) as r
    inner join #temp as t on(t.fcode=r.fcode and t.fdate<=r.fdate)
    --order by r.fcode,r.fdate
    ) as d where d.rank=1
    
    drop table #temp;
  • 相关阅读:
    java 问题记录
    java 构造方法
    java 接口
    java 抽象类
    java 封装
    java 面向对象
    java 集合小练习 超市库存管理系统
    linux常用指令
    个人简历表格
    html5 表格文档常用指令
  • 原文地址:https://www.cnblogs.com/gered/p/10394249.html
Copyright © 2020-2023  润新知