Add a row for every day between two dates with number of hours in SQL ServerAdd a column with a default value to an existing table in SQL ServerHow to return only the Date from a SQL Server DateTime datatypeWhat is the difference between char, nchar, varchar, and nvarchar in SQL Server?How to concatenate text from multiple rows into a single text string in SQL server?SQL Server: How to Join to first rowSum days between differing date/times progromaticallyT-SQL - DateTime Gap DistributionSQL Azure Calculate End to Start in Days Across Two Rows For RoomsCount number of rows between start and end dateSQL Server - Calculate the number of hours between two times and break out those hours into three time periods

Is it canonical bit space?

How do I write bicross product symbols in latex?

What is the most common color to indicate the input-field is disabled?

Forgetting the musical notes while performing in concert

What is the word for reserving something for yourself before others do?

I'm flying to France today and my passport expires in less than 2 months

Assassin's bullet with mercury

Will google still index a page if I use a $_SESSION variable?

Arrow those variables!

How is it possible to have an ability score that is less than 3?

What do you call someone who asks many questions?

What's the point of deactivating Num Lock on login screens?

How to show the equivalence between the regularized regression and their constraint formulas using KKT

Can I ask the recruiters in my resume to put the reason why I am rejected?

Doing something right before you need it - expression for this?

Alternative to sending password over mail?

Is it legal for company to use my work email to pretend I still work there?

I would say: "You are another teacher", but she is a woman and I am a man

What mechanic is there to disable a threat instead of killing it?

How can I fix/modify my tub/shower combo so the water comes out of the showerhead?

When a company launches a new product do they "come out" with a new product or do they "come up" with a new product?

Is it possible to run Internet Explorer on OS X El Capitan?

How to take photos in burst mode, without vibration?

Do I have a twin with permutated remainders?



Add a row for every day between two dates with number of hours in SQL Server


Add a column with a default value to an existing table in SQL ServerHow to return only the Date from a SQL Server DateTime datatypeWhat is the difference between char, nchar, varchar, and nvarchar in SQL Server?How to concatenate text from multiple rows into a single text string in SQL server?SQL Server: How to Join to first rowSum days between differing date/times progromaticallyT-SQL - DateTime Gap DistributionSQL Azure Calculate End to Start in Days Across Two Rows For RoomsCount number of rows between start and end dateSQL Server - Calculate the number of hours between two times and break out those hours into three time periods






.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty height:90px;width:728px;box-sizing:border-box;








0















Starting data:



enter image description here



Desired results something like this:



enter image description here



So it calculated the number of hours until the end of StartDateTime, if the EndDateTime is greater than end of day for StartDateTime. Then for every full day in between, it calculates 24 hours (this could stretch numerous days). And then when it gets to the EndDateTime - it calculates time from midnight (morning) to EndDateTime



I'm reading that I will probably need to use a recursive CTE, but I don't have any experience with recursions and am struggling.










share|improve this question
























  • Stackoverflow isn't a code writing service - you need to try something and then ask for assistance with the code you've tried.

    – Dale Burrell
    Mar 8 at 0:04











  • I've tried several different solutions that I just can't get to work. That's why I'm asking for some help. I don't really think it'd be much help for me to show several failed attempts

    – Djones
    Mar 8 at 0:19

















0















Starting data:



enter image description here



Desired results something like this:



enter image description here



So it calculated the number of hours until the end of StartDateTime, if the EndDateTime is greater than end of day for StartDateTime. Then for every full day in between, it calculates 24 hours (this could stretch numerous days). And then when it gets to the EndDateTime - it calculates time from midnight (morning) to EndDateTime



I'm reading that I will probably need to use a recursive CTE, but I don't have any experience with recursions and am struggling.










share|improve this question
























  • Stackoverflow isn't a code writing service - you need to try something and then ask for assistance with the code you've tried.

    – Dale Burrell
    Mar 8 at 0:04











  • I've tried several different solutions that I just can't get to work. That's why I'm asking for some help. I don't really think it'd be much help for me to show several failed attempts

    – Djones
    Mar 8 at 0:19













0












0








0








Starting data:



enter image description here



Desired results something like this:



enter image description here



So it calculated the number of hours until the end of StartDateTime, if the EndDateTime is greater than end of day for StartDateTime. Then for every full day in between, it calculates 24 hours (this could stretch numerous days). And then when it gets to the EndDateTime - it calculates time from midnight (morning) to EndDateTime



I'm reading that I will probably need to use a recursive CTE, but I don't have any experience with recursions and am struggling.










share|improve this question
















Starting data:



enter image description here



Desired results something like this:



enter image description here



So it calculated the number of hours until the end of StartDateTime, if the EndDateTime is greater than end of day for StartDateTime. Then for every full day in between, it calculates 24 hours (this could stretch numerous days). And then when it gets to the EndDateTime - it calculates time from midnight (morning) to EndDateTime



I'm reading that I will probably need to use a recursive CTE, but I don't have any experience with recursions and am struggling.







sql-server






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Mar 8 at 0:01









Dale Burrell

3,43452655




3,43452655










asked Mar 7 at 23:50









DjonesDjones

4916




4916












  • Stackoverflow isn't a code writing service - you need to try something and then ask for assistance with the code you've tried.

    – Dale Burrell
    Mar 8 at 0:04











  • I've tried several different solutions that I just can't get to work. That's why I'm asking for some help. I don't really think it'd be much help for me to show several failed attempts

    – Djones
    Mar 8 at 0:19

















  • Stackoverflow isn't a code writing service - you need to try something and then ask for assistance with the code you've tried.

    – Dale Burrell
    Mar 8 at 0:04











  • I've tried several different solutions that I just can't get to work. That's why I'm asking for some help. I don't really think it'd be much help for me to show several failed attempts

    – Djones
    Mar 8 at 0:19
















Stackoverflow isn't a code writing service - you need to try something and then ask for assistance with the code you've tried.

– Dale Burrell
Mar 8 at 0:04





Stackoverflow isn't a code writing service - you need to try something and then ask for assistance with the code you've tried.

– Dale Burrell
Mar 8 at 0:04













I've tried several different solutions that I just can't get to work. That's why I'm asking for some help. I don't really think it'd be much help for me to show several failed attempts

– Djones
Mar 8 at 0:19





I've tried several different solutions that I just can't get to work. That's why I'm asking for some help. I don't really think it'd be much help for me to show several failed attempts

– Djones
Mar 8 at 0:19












3 Answers
3






active

oldest

votes


















2














this might get tricky, but I guess it can be solved using so called number table - i.e. table which has only one column populated with number sequence. In our case 0 based sequence.



The trick here is to get the number of days between start and end datetime. This value used in join between the data table and the numbers table will create the needed extra rows for each per day interval.



Of course we also have to setup properly start and end datetime of each day interval (CASE terms in the CTE)



Then we get for each per day interval number of minutes and divide by 60 to get proper decimal value.



Hope this helps.



Lets see the code:



-- input data
DECLARE @v_Dates TABLE
(
id varchar(20),
StartDateTime SMALLDATETIME,
EndDateTime SMALLDATETIME
)

INSERT INTO @v_Dates (id, StartDateTime, EndDateTime)
VALUES ('example 1', '02-17-2019 0:45', '02-19-19 12:30'),
('example 2', '02-21-2019 18:00', '02-22-19 12:15'),
('example 3', '02-22-2019 20:15', '02-22-19 20:30');


-- so called Number table which holds numbers 0 - 9999 in this case
DECLARE @v_Numbers TABLE
(
Number INT
);

-- populating the number table
INSERT INTO @v_Numbers
SELECT TOP 10000 ROW_NUMBER() OVER(ORDER by t1.number) - 1 as Number
FROM master..spt_values t1
CROSS JOIN master..spt_values t2

-- we parse the dates into the per day intervals
;WITH IntervalsParsed(id, StartDateTime, EndDateTime, Number, IntervalStartDateTime, IntervalEndDateTime) AS
(
SELECT id
,StartDateTime
,EndDateTime
,Number
, InervalStartDateTime = CASE
WHEN D.StartDateTime > DATEADD(day, DATEDIFF(day, 0, D.StartDateTime), N.Number) THEN D.StartDateTime
ELSE DATEADD(day, DATEDIFF(day, 0, D.StartDateTime), N.Number)
END
, IntervalEndDateTime = CASE
WHEN D.EndDateTime < DATEADD(day, DATEDIFF(day, 0, D.StartDateTime), N.Number + 1) THEN D.EndDateTime
ELSE DATEADD(day, DATEDIFF(day, 0, D.StartDateTime), N.Number + 1)
END

FROM @v_Dates D
--this join basically creates the needed number of rows
INNER JOIN @v_Numbers N ON DATEDIFF(day, D.StartDateTime, D.EndDateTime) + 1 > N.Number
)
-- final select
SELECT id
, StartDateTime
, EndDateTime
, IntervalStartDateTime
, IntervalEndDateTime
, Number
, DecimalValue = CAST( DATEDIFF(minute, IntervalStartDateTime, IntervalEndDateTime) AS DECIMAL)/60

FROM IntervalsParsed
ORDER BY id, Number


enter image description here






share|improve this answer

























  • This worked exactly as needed. Thank you for the help!

    – Djones
    Mar 8 at 13:48


















2














Just another option is an ad-hoc tally table in concert with a CROSS APPLY



Example



Select A.[column1]
,A.[StartDateTime]
,A.[EndDateTime]
,Hours = sum(1) / 60.0
From @YourTable A
Cross Apply (
Select Top (DateDiff(MINUTE,[StartDateTime],[EndDateTime])+1)
D=DateAdd(MINUTE,-1+Row_Number() Over (Order By (Select Null)),[StartDateTime])
From master..spt_values n1,master..spt_values n2
) B
Group By [column1],[StartDateTime],[EndDateTime],cast(D as Date)


Returns



enter image description here






share|improve this answer






























    1














    This may be little complicated, but here is one way to use recursive cte to get the output. You can add the start date with one day as long as it is less than end date of your column. Also declared a Static value to make sure we can get difference of 24 hours.



    --Create a table



    Select 'example1' exm, '2019-02-17 00:45:00' startdate, '2019-02-19 12:30:00' Enddate into #temp union all 

    Select 'example2' exm, '2019-02-21 18:00:00' startdate, '2019-02-22 12:15:00' Enddate union all
    Select 'example3' exm, '2019-02-22 20:15:00' startdate, '2019-02-22 20:30:00' Enddate

    Declare @datevalue time = '23:59:59'

    ;with cte as (select exm, startdate, enddate, case when datediff(day, startdate, enddate) = 0 then datediff(SECOND, startdate, enddate)
    when datediff(day, startdate, enddate)>0 then
    datediff(SECOND, cast(startdate as time), @datevalue)
    end as Hoursn, cast(dateadd(day, 1,cast(startdate as date)) as smalldatetime) valueforhours from #temp
    union all
    select exm, startdate, enddate, case when datediff(day, valueforhours, enddate) = 0 then datediff(SECOND, valueforhours, enddate)
    when datediff(day, valueforhours, enddate)>0 then datediff(SECOND, cast(valueforhours as time), @datevalue) end as Hoursn, case when datediff(day,valueforhours, enddate) > 0 then dateadd(day,1,valueforhours) end as valueforhours
    from cte
    where
    valueforhours <= cast(enddate as date)
    )
    select exm, startdate, Enddate, round(Hoursn*1.0/3600,2) as [hours] from cte
    order by exm


    Output:



     exm startdate Enddate hours
    example1 2019-02-17 00:45:00 2019-02-19 12:30:00 23.250000
    example1 2019-02-17 00:45:00 2019-02-19 12:30:00 24.000000
    example1 2019-02-17 00:45:00 2019-02-19 12:30:00 12.500000
    example2 2019-02-21 18:00:00 2019-02-22 12:15:00 6.000000
    example2 2019-02-21 18:00:00 2019-02-22 12:15:00 12.250000
    example3 2019-02-22 20:15:00 2019-02-22 20:30:00 0.250000





    share|improve this answer























      Your Answer






      StackExchange.ifUsing("editor", function ()
      StackExchange.using("externalEditor", function ()
      StackExchange.using("snippets", function ()
      StackExchange.snippets.init();
      );
      );
      , "code-snippets");

      StackExchange.ready(function()
      var channelOptions =
      tags: "".split(" "),
      id: "1"
      ;
      initTagRenderer("".split(" "), "".split(" "), channelOptions);

      StackExchange.using("externalEditor", function()
      // Have to fire editor after snippets, if snippets enabled
      if (StackExchange.settings.snippets.snippetsEnabled)
      StackExchange.using("snippets", function()
      createEditor();
      );

      else
      createEditor();

      );

      function createEditor()
      StackExchange.prepareEditor(
      heartbeatType: 'answer',
      autoActivateHeartbeat: false,
      convertImagesToLinks: true,
      noModals: true,
      showLowRepImageUploadWarning: true,
      reputationToPostImages: 10,
      bindNavPrevention: true,
      postfix: "",
      imageUploader:
      brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
      contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
      allowUrls: true
      ,
      onDemand: true,
      discardSelector: ".discard-answer"
      ,immediatelyShowMarkdownHelp:true
      );



      );













      draft saved

      draft discarded


















      StackExchange.ready(
      function ()
      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55054652%2fadd-a-row-for-every-day-between-two-dates-with-number-of-hours-in-sql-server%23new-answer', 'question_page');

      );

      Post as a guest















      Required, but never shown

























      3 Answers
      3






      active

      oldest

      votes








      3 Answers
      3






      active

      oldest

      votes









      active

      oldest

      votes






      active

      oldest

      votes









      2














      this might get tricky, but I guess it can be solved using so called number table - i.e. table which has only one column populated with number sequence. In our case 0 based sequence.



      The trick here is to get the number of days between start and end datetime. This value used in join between the data table and the numbers table will create the needed extra rows for each per day interval.



      Of course we also have to setup properly start and end datetime of each day interval (CASE terms in the CTE)



      Then we get for each per day interval number of minutes and divide by 60 to get proper decimal value.



      Hope this helps.



      Lets see the code:



      -- input data
      DECLARE @v_Dates TABLE
      (
      id varchar(20),
      StartDateTime SMALLDATETIME,
      EndDateTime SMALLDATETIME
      )

      INSERT INTO @v_Dates (id, StartDateTime, EndDateTime)
      VALUES ('example 1', '02-17-2019 0:45', '02-19-19 12:30'),
      ('example 2', '02-21-2019 18:00', '02-22-19 12:15'),
      ('example 3', '02-22-2019 20:15', '02-22-19 20:30');


      -- so called Number table which holds numbers 0 - 9999 in this case
      DECLARE @v_Numbers TABLE
      (
      Number INT
      );

      -- populating the number table
      INSERT INTO @v_Numbers
      SELECT TOP 10000 ROW_NUMBER() OVER(ORDER by t1.number) - 1 as Number
      FROM master..spt_values t1
      CROSS JOIN master..spt_values t2

      -- we parse the dates into the per day intervals
      ;WITH IntervalsParsed(id, StartDateTime, EndDateTime, Number, IntervalStartDateTime, IntervalEndDateTime) AS
      (
      SELECT id
      ,StartDateTime
      ,EndDateTime
      ,Number
      , InervalStartDateTime = CASE
      WHEN D.StartDateTime > DATEADD(day, DATEDIFF(day, 0, D.StartDateTime), N.Number) THEN D.StartDateTime
      ELSE DATEADD(day, DATEDIFF(day, 0, D.StartDateTime), N.Number)
      END
      , IntervalEndDateTime = CASE
      WHEN D.EndDateTime < DATEADD(day, DATEDIFF(day, 0, D.StartDateTime), N.Number + 1) THEN D.EndDateTime
      ELSE DATEADD(day, DATEDIFF(day, 0, D.StartDateTime), N.Number + 1)
      END

      FROM @v_Dates D
      --this join basically creates the needed number of rows
      INNER JOIN @v_Numbers N ON DATEDIFF(day, D.StartDateTime, D.EndDateTime) + 1 > N.Number
      )
      -- final select
      SELECT id
      , StartDateTime
      , EndDateTime
      , IntervalStartDateTime
      , IntervalEndDateTime
      , Number
      , DecimalValue = CAST( DATEDIFF(minute, IntervalStartDateTime, IntervalEndDateTime) AS DECIMAL)/60

      FROM IntervalsParsed
      ORDER BY id, Number


      enter image description here






      share|improve this answer

























      • This worked exactly as needed. Thank you for the help!

        – Djones
        Mar 8 at 13:48















      2














      this might get tricky, but I guess it can be solved using so called number table - i.e. table which has only one column populated with number sequence. In our case 0 based sequence.



      The trick here is to get the number of days between start and end datetime. This value used in join between the data table and the numbers table will create the needed extra rows for each per day interval.



      Of course we also have to setup properly start and end datetime of each day interval (CASE terms in the CTE)



      Then we get for each per day interval number of minutes and divide by 60 to get proper decimal value.



      Hope this helps.



      Lets see the code:



      -- input data
      DECLARE @v_Dates TABLE
      (
      id varchar(20),
      StartDateTime SMALLDATETIME,
      EndDateTime SMALLDATETIME
      )

      INSERT INTO @v_Dates (id, StartDateTime, EndDateTime)
      VALUES ('example 1', '02-17-2019 0:45', '02-19-19 12:30'),
      ('example 2', '02-21-2019 18:00', '02-22-19 12:15'),
      ('example 3', '02-22-2019 20:15', '02-22-19 20:30');


      -- so called Number table which holds numbers 0 - 9999 in this case
      DECLARE @v_Numbers TABLE
      (
      Number INT
      );

      -- populating the number table
      INSERT INTO @v_Numbers
      SELECT TOP 10000 ROW_NUMBER() OVER(ORDER by t1.number) - 1 as Number
      FROM master..spt_values t1
      CROSS JOIN master..spt_values t2

      -- we parse the dates into the per day intervals
      ;WITH IntervalsParsed(id, StartDateTime, EndDateTime, Number, IntervalStartDateTime, IntervalEndDateTime) AS
      (
      SELECT id
      ,StartDateTime
      ,EndDateTime
      ,Number
      , InervalStartDateTime = CASE
      WHEN D.StartDateTime > DATEADD(day, DATEDIFF(day, 0, D.StartDateTime), N.Number) THEN D.StartDateTime
      ELSE DATEADD(day, DATEDIFF(day, 0, D.StartDateTime), N.Number)
      END
      , IntervalEndDateTime = CASE
      WHEN D.EndDateTime < DATEADD(day, DATEDIFF(day, 0, D.StartDateTime), N.Number + 1) THEN D.EndDateTime
      ELSE DATEADD(day, DATEDIFF(day, 0, D.StartDateTime), N.Number + 1)
      END

      FROM @v_Dates D
      --this join basically creates the needed number of rows
      INNER JOIN @v_Numbers N ON DATEDIFF(day, D.StartDateTime, D.EndDateTime) + 1 > N.Number
      )
      -- final select
      SELECT id
      , StartDateTime
      , EndDateTime
      , IntervalStartDateTime
      , IntervalEndDateTime
      , Number
      , DecimalValue = CAST( DATEDIFF(minute, IntervalStartDateTime, IntervalEndDateTime) AS DECIMAL)/60

      FROM IntervalsParsed
      ORDER BY id, Number


      enter image description here






      share|improve this answer

























      • This worked exactly as needed. Thank you for the help!

        – Djones
        Mar 8 at 13:48













      2












      2








      2







      this might get tricky, but I guess it can be solved using so called number table - i.e. table which has only one column populated with number sequence. In our case 0 based sequence.



      The trick here is to get the number of days between start and end datetime. This value used in join between the data table and the numbers table will create the needed extra rows for each per day interval.



      Of course we also have to setup properly start and end datetime of each day interval (CASE terms in the CTE)



      Then we get for each per day interval number of minutes and divide by 60 to get proper decimal value.



      Hope this helps.



      Lets see the code:



      -- input data
      DECLARE @v_Dates TABLE
      (
      id varchar(20),
      StartDateTime SMALLDATETIME,
      EndDateTime SMALLDATETIME
      )

      INSERT INTO @v_Dates (id, StartDateTime, EndDateTime)
      VALUES ('example 1', '02-17-2019 0:45', '02-19-19 12:30'),
      ('example 2', '02-21-2019 18:00', '02-22-19 12:15'),
      ('example 3', '02-22-2019 20:15', '02-22-19 20:30');


      -- so called Number table which holds numbers 0 - 9999 in this case
      DECLARE @v_Numbers TABLE
      (
      Number INT
      );

      -- populating the number table
      INSERT INTO @v_Numbers
      SELECT TOP 10000 ROW_NUMBER() OVER(ORDER by t1.number) - 1 as Number
      FROM master..spt_values t1
      CROSS JOIN master..spt_values t2

      -- we parse the dates into the per day intervals
      ;WITH IntervalsParsed(id, StartDateTime, EndDateTime, Number, IntervalStartDateTime, IntervalEndDateTime) AS
      (
      SELECT id
      ,StartDateTime
      ,EndDateTime
      ,Number
      , InervalStartDateTime = CASE
      WHEN D.StartDateTime > DATEADD(day, DATEDIFF(day, 0, D.StartDateTime), N.Number) THEN D.StartDateTime
      ELSE DATEADD(day, DATEDIFF(day, 0, D.StartDateTime), N.Number)
      END
      , IntervalEndDateTime = CASE
      WHEN D.EndDateTime < DATEADD(day, DATEDIFF(day, 0, D.StartDateTime), N.Number + 1) THEN D.EndDateTime
      ELSE DATEADD(day, DATEDIFF(day, 0, D.StartDateTime), N.Number + 1)
      END

      FROM @v_Dates D
      --this join basically creates the needed number of rows
      INNER JOIN @v_Numbers N ON DATEDIFF(day, D.StartDateTime, D.EndDateTime) + 1 > N.Number
      )
      -- final select
      SELECT id
      , StartDateTime
      , EndDateTime
      , IntervalStartDateTime
      , IntervalEndDateTime
      , Number
      , DecimalValue = CAST( DATEDIFF(minute, IntervalStartDateTime, IntervalEndDateTime) AS DECIMAL)/60

      FROM IntervalsParsed
      ORDER BY id, Number


      enter image description here






      share|improve this answer















      this might get tricky, but I guess it can be solved using so called number table - i.e. table which has only one column populated with number sequence. In our case 0 based sequence.



      The trick here is to get the number of days between start and end datetime. This value used in join between the data table and the numbers table will create the needed extra rows for each per day interval.



      Of course we also have to setup properly start and end datetime of each day interval (CASE terms in the CTE)



      Then we get for each per day interval number of minutes and divide by 60 to get proper decimal value.



      Hope this helps.



      Lets see the code:



      -- input data
      DECLARE @v_Dates TABLE
      (
      id varchar(20),
      StartDateTime SMALLDATETIME,
      EndDateTime SMALLDATETIME
      )

      INSERT INTO @v_Dates (id, StartDateTime, EndDateTime)
      VALUES ('example 1', '02-17-2019 0:45', '02-19-19 12:30'),
      ('example 2', '02-21-2019 18:00', '02-22-19 12:15'),
      ('example 3', '02-22-2019 20:15', '02-22-19 20:30');


      -- so called Number table which holds numbers 0 - 9999 in this case
      DECLARE @v_Numbers TABLE
      (
      Number INT
      );

      -- populating the number table
      INSERT INTO @v_Numbers
      SELECT TOP 10000 ROW_NUMBER() OVER(ORDER by t1.number) - 1 as Number
      FROM master..spt_values t1
      CROSS JOIN master..spt_values t2

      -- we parse the dates into the per day intervals
      ;WITH IntervalsParsed(id, StartDateTime, EndDateTime, Number, IntervalStartDateTime, IntervalEndDateTime) AS
      (
      SELECT id
      ,StartDateTime
      ,EndDateTime
      ,Number
      , InervalStartDateTime = CASE
      WHEN D.StartDateTime > DATEADD(day, DATEDIFF(day, 0, D.StartDateTime), N.Number) THEN D.StartDateTime
      ELSE DATEADD(day, DATEDIFF(day, 0, D.StartDateTime), N.Number)
      END
      , IntervalEndDateTime = CASE
      WHEN D.EndDateTime < DATEADD(day, DATEDIFF(day, 0, D.StartDateTime), N.Number + 1) THEN D.EndDateTime
      ELSE DATEADD(day, DATEDIFF(day, 0, D.StartDateTime), N.Number + 1)
      END

      FROM @v_Dates D
      --this join basically creates the needed number of rows
      INNER JOIN @v_Numbers N ON DATEDIFF(day, D.StartDateTime, D.EndDateTime) + 1 > N.Number
      )
      -- final select
      SELECT id
      , StartDateTime
      , EndDateTime
      , IntervalStartDateTime
      , IntervalEndDateTime
      , Number
      , DecimalValue = CAST( DATEDIFF(minute, IntervalStartDateTime, IntervalEndDateTime) AS DECIMAL)/60

      FROM IntervalsParsed
      ORDER BY id, Number


      enter image description here







      share|improve this answer














      share|improve this answer



      share|improve this answer








      edited Mar 8 at 1:57

























      answered Mar 8 at 1:52









      EmilEmil

      174214




      174214












      • This worked exactly as needed. Thank you for the help!

        – Djones
        Mar 8 at 13:48

















      • This worked exactly as needed. Thank you for the help!

        – Djones
        Mar 8 at 13:48
















      This worked exactly as needed. Thank you for the help!

      – Djones
      Mar 8 at 13:48





      This worked exactly as needed. Thank you for the help!

      – Djones
      Mar 8 at 13:48













      2














      Just another option is an ad-hoc tally table in concert with a CROSS APPLY



      Example



      Select A.[column1]
      ,A.[StartDateTime]
      ,A.[EndDateTime]
      ,Hours = sum(1) / 60.0
      From @YourTable A
      Cross Apply (
      Select Top (DateDiff(MINUTE,[StartDateTime],[EndDateTime])+1)
      D=DateAdd(MINUTE,-1+Row_Number() Over (Order By (Select Null)),[StartDateTime])
      From master..spt_values n1,master..spt_values n2
      ) B
      Group By [column1],[StartDateTime],[EndDateTime],cast(D as Date)


      Returns



      enter image description here






      share|improve this answer



























        2














        Just another option is an ad-hoc tally table in concert with a CROSS APPLY



        Example



        Select A.[column1]
        ,A.[StartDateTime]
        ,A.[EndDateTime]
        ,Hours = sum(1) / 60.0
        From @YourTable A
        Cross Apply (
        Select Top (DateDiff(MINUTE,[StartDateTime],[EndDateTime])+1)
        D=DateAdd(MINUTE,-1+Row_Number() Over (Order By (Select Null)),[StartDateTime])
        From master..spt_values n1,master..spt_values n2
        ) B
        Group By [column1],[StartDateTime],[EndDateTime],cast(D as Date)


        Returns



        enter image description here






        share|improve this answer

























          2












          2








          2







          Just another option is an ad-hoc tally table in concert with a CROSS APPLY



          Example



          Select A.[column1]
          ,A.[StartDateTime]
          ,A.[EndDateTime]
          ,Hours = sum(1) / 60.0
          From @YourTable A
          Cross Apply (
          Select Top (DateDiff(MINUTE,[StartDateTime],[EndDateTime])+1)
          D=DateAdd(MINUTE,-1+Row_Number() Over (Order By (Select Null)),[StartDateTime])
          From master..spt_values n1,master..spt_values n2
          ) B
          Group By [column1],[StartDateTime],[EndDateTime],cast(D as Date)


          Returns



          enter image description here






          share|improve this answer













          Just another option is an ad-hoc tally table in concert with a CROSS APPLY



          Example



          Select A.[column1]
          ,A.[StartDateTime]
          ,A.[EndDateTime]
          ,Hours = sum(1) / 60.0
          From @YourTable A
          Cross Apply (
          Select Top (DateDiff(MINUTE,[StartDateTime],[EndDateTime])+1)
          D=DateAdd(MINUTE,-1+Row_Number() Over (Order By (Select Null)),[StartDateTime])
          From master..spt_values n1,master..spt_values n2
          ) B
          Group By [column1],[StartDateTime],[EndDateTime],cast(D as Date)


          Returns



          enter image description here







          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered Mar 8 at 1:54









          John CappellettiJohn Cappelletti

          47.4k62647




          47.4k62647





















              1














              This may be little complicated, but here is one way to use recursive cte to get the output. You can add the start date with one day as long as it is less than end date of your column. Also declared a Static value to make sure we can get difference of 24 hours.



              --Create a table



              Select 'example1' exm, '2019-02-17 00:45:00' startdate, '2019-02-19 12:30:00' Enddate into #temp union all 

              Select 'example2' exm, '2019-02-21 18:00:00' startdate, '2019-02-22 12:15:00' Enddate union all
              Select 'example3' exm, '2019-02-22 20:15:00' startdate, '2019-02-22 20:30:00' Enddate

              Declare @datevalue time = '23:59:59'

              ;with cte as (select exm, startdate, enddate, case when datediff(day, startdate, enddate) = 0 then datediff(SECOND, startdate, enddate)
              when datediff(day, startdate, enddate)>0 then
              datediff(SECOND, cast(startdate as time), @datevalue)
              end as Hoursn, cast(dateadd(day, 1,cast(startdate as date)) as smalldatetime) valueforhours from #temp
              union all
              select exm, startdate, enddate, case when datediff(day, valueforhours, enddate) = 0 then datediff(SECOND, valueforhours, enddate)
              when datediff(day, valueforhours, enddate)>0 then datediff(SECOND, cast(valueforhours as time), @datevalue) end as Hoursn, case when datediff(day,valueforhours, enddate) > 0 then dateadd(day,1,valueforhours) end as valueforhours
              from cte
              where
              valueforhours <= cast(enddate as date)
              )
              select exm, startdate, Enddate, round(Hoursn*1.0/3600,2) as [hours] from cte
              order by exm


              Output:



               exm startdate Enddate hours
              example1 2019-02-17 00:45:00 2019-02-19 12:30:00 23.250000
              example1 2019-02-17 00:45:00 2019-02-19 12:30:00 24.000000
              example1 2019-02-17 00:45:00 2019-02-19 12:30:00 12.500000
              example2 2019-02-21 18:00:00 2019-02-22 12:15:00 6.000000
              example2 2019-02-21 18:00:00 2019-02-22 12:15:00 12.250000
              example3 2019-02-22 20:15:00 2019-02-22 20:30:00 0.250000





              share|improve this answer



























                1














                This may be little complicated, but here is one way to use recursive cte to get the output. You can add the start date with one day as long as it is less than end date of your column. Also declared a Static value to make sure we can get difference of 24 hours.



                --Create a table



                Select 'example1' exm, '2019-02-17 00:45:00' startdate, '2019-02-19 12:30:00' Enddate into #temp union all 

                Select 'example2' exm, '2019-02-21 18:00:00' startdate, '2019-02-22 12:15:00' Enddate union all
                Select 'example3' exm, '2019-02-22 20:15:00' startdate, '2019-02-22 20:30:00' Enddate

                Declare @datevalue time = '23:59:59'

                ;with cte as (select exm, startdate, enddate, case when datediff(day, startdate, enddate) = 0 then datediff(SECOND, startdate, enddate)
                when datediff(day, startdate, enddate)>0 then
                datediff(SECOND, cast(startdate as time), @datevalue)
                end as Hoursn, cast(dateadd(day, 1,cast(startdate as date)) as smalldatetime) valueforhours from #temp
                union all
                select exm, startdate, enddate, case when datediff(day, valueforhours, enddate) = 0 then datediff(SECOND, valueforhours, enddate)
                when datediff(day, valueforhours, enddate)>0 then datediff(SECOND, cast(valueforhours as time), @datevalue) end as Hoursn, case when datediff(day,valueforhours, enddate) > 0 then dateadd(day,1,valueforhours) end as valueforhours
                from cte
                where
                valueforhours <= cast(enddate as date)
                )
                select exm, startdate, Enddate, round(Hoursn*1.0/3600,2) as [hours] from cte
                order by exm


                Output:



                 exm startdate Enddate hours
                example1 2019-02-17 00:45:00 2019-02-19 12:30:00 23.250000
                example1 2019-02-17 00:45:00 2019-02-19 12:30:00 24.000000
                example1 2019-02-17 00:45:00 2019-02-19 12:30:00 12.500000
                example2 2019-02-21 18:00:00 2019-02-22 12:15:00 6.000000
                example2 2019-02-21 18:00:00 2019-02-22 12:15:00 12.250000
                example3 2019-02-22 20:15:00 2019-02-22 20:30:00 0.250000





                share|improve this answer

























                  1












                  1








                  1







                  This may be little complicated, but here is one way to use recursive cte to get the output. You can add the start date with one day as long as it is less than end date of your column. Also declared a Static value to make sure we can get difference of 24 hours.



                  --Create a table



                  Select 'example1' exm, '2019-02-17 00:45:00' startdate, '2019-02-19 12:30:00' Enddate into #temp union all 

                  Select 'example2' exm, '2019-02-21 18:00:00' startdate, '2019-02-22 12:15:00' Enddate union all
                  Select 'example3' exm, '2019-02-22 20:15:00' startdate, '2019-02-22 20:30:00' Enddate

                  Declare @datevalue time = '23:59:59'

                  ;with cte as (select exm, startdate, enddate, case when datediff(day, startdate, enddate) = 0 then datediff(SECOND, startdate, enddate)
                  when datediff(day, startdate, enddate)>0 then
                  datediff(SECOND, cast(startdate as time), @datevalue)
                  end as Hoursn, cast(dateadd(day, 1,cast(startdate as date)) as smalldatetime) valueforhours from #temp
                  union all
                  select exm, startdate, enddate, case when datediff(day, valueforhours, enddate) = 0 then datediff(SECOND, valueforhours, enddate)
                  when datediff(day, valueforhours, enddate)>0 then datediff(SECOND, cast(valueforhours as time), @datevalue) end as Hoursn, case when datediff(day,valueforhours, enddate) > 0 then dateadd(day,1,valueforhours) end as valueforhours
                  from cte
                  where
                  valueforhours <= cast(enddate as date)
                  )
                  select exm, startdate, Enddate, round(Hoursn*1.0/3600,2) as [hours] from cte
                  order by exm


                  Output:



                   exm startdate Enddate hours
                  example1 2019-02-17 00:45:00 2019-02-19 12:30:00 23.250000
                  example1 2019-02-17 00:45:00 2019-02-19 12:30:00 24.000000
                  example1 2019-02-17 00:45:00 2019-02-19 12:30:00 12.500000
                  example2 2019-02-21 18:00:00 2019-02-22 12:15:00 6.000000
                  example2 2019-02-21 18:00:00 2019-02-22 12:15:00 12.250000
                  example3 2019-02-22 20:15:00 2019-02-22 20:30:00 0.250000





                  share|improve this answer













                  This may be little complicated, but here is one way to use recursive cte to get the output. You can add the start date with one day as long as it is less than end date of your column. Also declared a Static value to make sure we can get difference of 24 hours.



                  --Create a table



                  Select 'example1' exm, '2019-02-17 00:45:00' startdate, '2019-02-19 12:30:00' Enddate into #temp union all 

                  Select 'example2' exm, '2019-02-21 18:00:00' startdate, '2019-02-22 12:15:00' Enddate union all
                  Select 'example3' exm, '2019-02-22 20:15:00' startdate, '2019-02-22 20:30:00' Enddate

                  Declare @datevalue time = '23:59:59'

                  ;with cte as (select exm, startdate, enddate, case when datediff(day, startdate, enddate) = 0 then datediff(SECOND, startdate, enddate)
                  when datediff(day, startdate, enddate)>0 then
                  datediff(SECOND, cast(startdate as time), @datevalue)
                  end as Hoursn, cast(dateadd(day, 1,cast(startdate as date)) as smalldatetime) valueforhours from #temp
                  union all
                  select exm, startdate, enddate, case when datediff(day, valueforhours, enddate) = 0 then datediff(SECOND, valueforhours, enddate)
                  when datediff(day, valueforhours, enddate)>0 then datediff(SECOND, cast(valueforhours as time), @datevalue) end as Hoursn, case when datediff(day,valueforhours, enddate) > 0 then dateadd(day,1,valueforhours) end as valueforhours
                  from cte
                  where
                  valueforhours <= cast(enddate as date)
                  )
                  select exm, startdate, Enddate, round(Hoursn*1.0/3600,2) as [hours] from cte
                  order by exm


                  Output:



                   exm startdate Enddate hours
                  example1 2019-02-17 00:45:00 2019-02-19 12:30:00 23.250000
                  example1 2019-02-17 00:45:00 2019-02-19 12:30:00 24.000000
                  example1 2019-02-17 00:45:00 2019-02-19 12:30:00 12.500000
                  example2 2019-02-21 18:00:00 2019-02-22 12:15:00 6.000000
                  example2 2019-02-21 18:00:00 2019-02-22 12:15:00 12.250000
                  example3 2019-02-22 20:15:00 2019-02-22 20:30:00 0.250000






                  share|improve this answer












                  share|improve this answer



                  share|improve this answer










                  answered Mar 8 at 4:46









                  AviAvi

                  809314




                  809314



























                      draft saved

                      draft discarded
















































                      Thanks for contributing an answer to Stack Overflow!


                      • Please be sure to answer the question. Provide details and share your research!

                      But avoid


                      • Asking for help, clarification, or responding to other answers.

                      • Making statements based on opinion; back them up with references or personal experience.

                      To learn more, see our tips on writing great answers.




                      draft saved


                      draft discarded














                      StackExchange.ready(
                      function ()
                      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55054652%2fadd-a-row-for-every-day-between-two-dates-with-number-of-hours-in-sql-server%23new-answer', 'question_page');

                      );

                      Post as a guest















                      Required, but never shown





















































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown

































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown







                      Popular posts from this blog

                      1928 у кіно

                      Захаров Федір Захарович

                      Ель Греко