SQL-根据月份将行拆分为多个

时间:2018-07-04 14:53:31

标签: sql-server

  

我在SQL(2012)表中连续有以下数据

     

ID Value StartDate EndDate 123 5000 14/04/2017 15/12/2017

     

我想将行分成每个月,如下所示:

ID Value StartDate EndDate 123 5000 14/04/2017 30/04/2017 123 5000 01/05/2017 31/05/2017 123 5000 01/06/2017 30/06/2017 123 5000 01/07/2017 31/07/2017 123 5000 01/08/2017 30/08/2017 123 5000 01/09/2017 31/09/2017 123 5000 01/10/2017 31/10/2017 123 5000 01/11/2017 30/11/2017 123 5000 01/12/2017 15/12/2017

  

在此问题上提供帮助。

2 个答案:

答案 0 :(得分:0)

您可以这样做:

WITH tally
AS (SELECT TOP (1000)
           ROW_NUMBER() OVER (ORDER BY t1.object_id) AS N
    FROM master.sys.all_columns t1
        CROSS JOIN master.sys.all_columns t2),
     rowset
AS (SELECT ID,
           Value,
           DATEADD(m, N - 1, StartDate) AS StartDate,
           Enddate,
           N
    FROM tally, MyDates
    WHERE DATEFROMPARTS(YEAR(DATEADD(m, N - 1, StartDate)), 
    MONTH(DATEADD(m, N - 1, StartDate)), 1) <= EndDate) 
SELECT Id,
       Value,
       CASE
           WHEN N = 1 THEN
               StartDate
           ELSE
               DATEFROMPARTS(YEAR(StartDate), MONTH(StartDate), 1)
       END AS StartDate,
       CASE
           WHEN DATEADD(d, -DAY(DATEADD(m, 1, StartDate)), DATEADD(m, 1, StartDate)) <= EndDate THEN
               DATEADD(d, -DAY(DATEADD(m, 1, StartDate)), DATEADD(m, 1, StartDate))
           ELSE
               Enddate
       END AS EndDate
FROM rowset
ORDER BY ID, StartDate;

答案 1 :(得分:-1)

Use below query to get the result

DECLARE @Temp TABLE
(
    ID INT
    ,Value NUMERIC(10,2)
    ,StartDate DATE
    ,EndDate DATE
)

DECLARE @NewTable TABLE
(
    id INT IDENTITY(1,1)
    ,item INT
    ,Value NUMERIC(10,2)
    ,StartDate DATE
    ,EndDate DATE
)

INSERT INTO @Temp
SELECT 123,5000    ,'2017-04-14','2018-12-15'

DECLARE @SDate date
DECLARE @EDate date
declare @LastDay INT =0

 SELECT top 1 @SDate=StartDate,@EDate=EndDate  FROM @Temp     


 declare @Year int = 0
 declare @Month int = 0


declare @Index INT =1
DECLARE @Lenght int =DATEDIFF(MONTH,@SDate,@EDate) +1



WHILE @Index<=@Lenght
BEGIN

    IF @Index=1 BEGIN
       -- first record
       SELECT @Year= YEAR(@SDate)
       SELECT @Month = MONTH(@SDate)
       -- get last day of the date
       SELECT @LastDay = day(DATEADD(s,-1,DATEADD(mm, DATEDIFF(m,0,@SDate)+1,0)))       
       SELECT @EDate= CONVERT(VARCHAR(10),@Year)+'-'+CONVERT(VARCHAR(10),@Month)+'- 
 '+CONVERT(VARCHAR(10),@LastDay)        
    INSERT INTO @NewTable
    SELECT 123,5000,@SDate, @EDate
  END ELSE IF @Index = @Lenght BEGIN
    SELECT @Month = @Month+1
    IF @Month>12 BEGIN
        SELECT @Month =1
        SELECT @Year =@Year +1
    END ELSE BEGIN
        SELECT @Year= YEAR(@EDate)
    END
    SELECT @SDate =CONVERT(VARCHAR(10),@Year)+'-'+CONVERT(VARCHAR(10),@Month)+ '-01'
    INSERT INTO @NewTable
    SELECT 123,5000    ,@SDate,@EDate
END ELSE BEGIN

    SELECT @Month = @Month+1
    if @Month>12 BEGIN
        SELECT @Month =1
        SELECT @Year =@Year +1
    END


    SELECT @SDate =CONVERT(VARCHAR(10),@Year)+'-'+CONVERT(VARCHAR(10),@Month)+ '-01'

    SELECT @LastDay = day(DATEADD(s,-1,DATEADD(mm, DATEDIFF(m,0,@SDate)+1,0)))
    SELECT @EDate= CONVERT(VARCHAR(10),@Year)+'-'+CONVERT(VARCHAR(10),@Month)+'-'+CONVERT(VARCHAR(10),@LastDay) 

    INSERT INTO @NewTable
    SELECT 123,5000    ,@SDate,@EDate


END


SELECT @Index=@Index+1

结束

SELECT * from @NewTable

-选择日期(DATEADD(s,-1,DATEADD(mm,DATEDIFF(m,0,getdate())+ 1,0)))