sql将月份数据拆分为天到日期行

kxxlusnw  于 2021-07-27  发布在  Java
关注(0)|答案(2)|浏览(420)

我在SQLServer中有一个表,上面有每月的目标单位。

select TargetDate, Units
FROM TargetTable;

TargetDate  Units
2020-01-01  62
2020-02-01  87
2020-03-01  104
2020-04-01  109

我希望单位由日期-除以总单位的天数,在该月-有天和日单位行。。。像这样:

TargetDate  Units
2020-01-01  2
2020-01-02  2
2020-01-03  2
2020-01-04  2
    .
    .
    .
2020-02-01  3

我对sql的理解还处于初级阶段,如果您能给我任何帮助,我将不胜感激。
短暂性脑缺血发作

anauzrmj

anauzrmj1#

一个选项使用递归查询:

with cte as (
    select 
        targetdate, 
        eomonth(targetdate) enddate, 
        1.0 * units / day(eomonth(targetdate)) units
    from targettable
    union all
    select dateadd(day, 1, targetdate), enddate, units 
    from cte
    where targetdate < enddate
)
select targetdate, units from cte

笔记:
我想 units 不会总是一个月天数的倍数,所以这会给你一个十进制值而不是整数。
如果您需要处理超过100天(大约3个月的数据),那么您需要添加 option (max recursion 0) 在查询的末尾。 eomonth() 是在sql server 2012中引入的(早期版本中有替代方案)

lvjbypge

lvjbypge2#

SELECT 
  targetDate, 
  DATEADD(day, a, targetDate) as dd, 
  CAST(units as FLOAT) / DAY(EOMONTH(targetdate)) as uu

FROM 
    ( 
        VALUES 
        (0),(1),(2),(3),(4),(5),(6),(7),(8),(9),
        (10),(11),(12),(13),(14),(15),(16),(17),(18),(19),
        (20),(21),(22),(23),(24),(25),(26),(27),(28),(29),(30)
    ) a(a)

    CROSS JOIN

    /*
    (SELECT CAST('2020-01-01' as date) targetdate, 62 as units  UNION ALL 
     SELECT CAST('2020-02-01' as date), 87 UNION ALL 
     SELECT CAST('2020-03-01' as date), 104
    )x*/
    targetTable

WHERE 
   DATEADD(day, a, targetdate) <= EOMONTH(targetdate)

工作原理:
我们生成一个从0到30的数字块,并将现有数据与之交叉,给出2020-01-01的31次重复,2020-02-01的31次重复,2020-03-01的31次重复等。

2020-01-01, 0
2020-01-01, 1
2020-01-01, 2
...

如果我们将数字(以天为单位)加到日期上,则给出一个日期,该日期在整个月内滚动,但有些日期超出了下个月:

2020-01-01, 0, 2020-01-01
2020-01-01, 1, 2020-01-02
2020-01-01, 2, 2020-01-03
...
2020-02-01, 28, 2020-02-29
2020-02-01, 29, 2020-03-01 --it's march!
2020-02-01, 30, 2020-03-02 --it's march!

我们使用where子句通过确保添加的日期小于或等于eomonth(targetdate)来删除超出的日期-eomonth返回一个日期,该日期是传入日期的当月最后一天
所以我们得到了递增的日期,我们只需要每天的单位数-除以这个月的天数(由月的第几天给出)。我们将单位转换为浮点数,以便sqlserver使用小数而不是整数进行除法(否则60/31是1)
如果你没有 EOMONTH 可以使用的函数 DATEADD(DAY, -1, DATEADD(MONTH, 1 targetdate)) 向前滚一个月,向后滚一天

相关问题