Query - Start Date, End Date count for each year

  • Need help to find the count between start date and end date.

    Below query shows only count in Y2006 year, i want to display each year count 1, because start date and end date is valid for each year

    CREATE TABLE [dbo].[T1](

    [STRTDATE] [datetime] NOT NULL,

    [ENDDATE] [datetime] NOT NULL

    )

    INSERT INTO T1

    SELECT '2006-03-09', '2011-03-08'

    SELECT

    SUM(CASE WHEN STRTDATE >= '2006-01-01' AND STRTDATE <= '2006-12-31' THEN 1 ELSE 0 END) AS Y2006,

    SUM(CASE WHEN STRTDATE >= '2007-01-01' AND STRTDATE <= '2007-12-31' THEN 1 ELSE 0 END) AS Y2007,

    SUM(CASE WHEN STRTDATE >= '2008-01-01' AND STRTDATE <= '2008-12-31' THEN 1 ELSE 0 END) AS Y2008,

    SUM(CASE WHEN STRTDATE >= '2009-01-01' AND STRTDATE <= '2009-12-31' THEN 1 ELSE 0 END) AS Y2009,

    SUM(CASE WHEN STRTDATE >= '2010-01-01' AND STRTDATE <= '2010-12-31' THEN 1 ELSE 0 END) AS Y2010,

    SUM(CASE WHEN STRTDATE >= '2011-01-01' AND STRTDATE <= '2011-12-31' THEN 1 ELSE 0 END) AS Y2010

    FROM T1

  • try:

    SELECT

    SUM(CASE WHEN 2006 BETWEEN YEAR(STRTDATE) AND YEAR(ENDDATE) THEN 1 ELSE 0 END) AS Y2006,

    SUM(CASE WHEN 2007 BETWEEN YEAR(STRTDATE) AND YEAR(ENDDATE) THEN 1 ELSE 0 END) AS Y2007,

    SUM(CASE WHEN 2008 BETWEEN YEAR(STRTDATE) AND YEAR(ENDDATE) THEN 1 ELSE 0 END) AS Y2008,

    SUM(CASE WHEN 2009 BETWEEN YEAR(STRTDATE) AND YEAR(ENDDATE) THEN 1 ELSE 0 END) AS Y2009,

    SUM(CASE WHEN 2010 BETWEEN YEAR(STRTDATE) AND YEAR(ENDDATE) THEN 1 ELSE 0 END) AS Y2010,

    SUM(CASE WHEN 2011 BETWEEN YEAR(STRTDATE) AND YEAR(ENDDATE) THEN 1 ELSE 0 END) AS Y2011,

    SUM(CASE WHEN 2005 BETWEEN YEAR(STRTDATE) AND YEAR(ENDDATE) THEN 1 ELSE 0 END) AS Y2005,

    SUM(CASE WHEN 2012 BETWEEN YEAR(STRTDATE) AND YEAR(ENDDATE) THEN 1 ELSE 0 END) AS Y2012

    FROM T1

    I have also added 2005 and 2012, to show that they are not counted!

    _____________________________________________
    "The only true wisdom is in knowing you know nothing"
    "O skol'ko nam otkrytiy chudnyh prevnosit microsofta duh!":-D
    (So many miracle inventions provided by MS to us...)

    How to post your question to get the best and quick help[/url]

  • Thank you so much for the help.

  • You are welcome!

    _____________________________________________
    "The only true wisdom is in knowing you know nothing"
    "O skol'ko nam otkrytiy chudnyh prevnosit microsofta duh!":-D
    (So many miracle inventions provided by MS to us...)

    How to post your question to get the best and quick help[/url]

  • The problem I have with the case statements is that they're a bit ugly to work with (especially when you get more and more) and they're not dynamic. So, in this example the query may work fine until 2012 but if someone forgets to update the query and add more years it will eventually fail in terms of accuracy. I would suggest using a tally table for this kind of operation.

    --If you don't already have a tally table in place ...

    ;WITH --"Inline" CTE Driven "Tally Table" produces values up to 10K... enough to cover VARCHAR(8000).

    E1(N) AS (SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL

    SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL

    SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1),--10

    E2(N) AS (SELECT 1 FROM E1 a, E1 b), --100

    E4(N) AS (SELECT 1 FROM E2 a, E2 b), --10,000

    cteTally(N) AS (SELECT ROW_NUMBER() OVER (ORDER BY N) FROM E4)

    --actual query

    select t.STRTDATE,

    t.ENDDATE,

    'Y' + CAST(N as varchar) as theYear

    from #temp t

    join cteTally cte

    on cte.N between year(t.STRTDATE) and year(t.ENDDATE)

    └> bt



    Forum Etiquette: How to post data/code on a forum to get the best help[/url]

  • And not sure if you ultimately just want the count of the years which would be:

    --actual query

    select sq.STRTDATE,

    sq.ENDDATE,

    COUNT(sq.myYear) as yearCount

    from

    (

    select t.STRTDATE,

    t.ENDDATE,

    'Y' + CAST(N as varchar) as myYear

    from #temp t

    join cteTally cte

    on cte.N between year(t.STRTDATE) and year(t.ENDDATE)

    ) sq

    group by sq.STRTDATE, sq.ENDDATE

    └> bt



    Forum Etiquette: How to post data/code on a forum to get the best help[/url]

  • bteraberry (7/14/2010)


    The problem I have with the case statements is that they're a bit ugly to work with (especially when you get more and more) and they're not dynamic

    ...

    1. We are not afraid of "dirty" work here 😀

    2. The task given looks like just an one-off query, for which I don't thing you need to over engineer solution.

    3. OP wanted pivoted result.

    _____________________________________________
    "The only true wisdom is in knowing you know nothing"
    "O skol'ko nam otkrytiy chudnyh prevnosit microsofta duh!":-D
    (So many miracle inventions provided by MS to us...)

    How to post your question to get the best and quick help[/url]

  • OFF-TOPIC:

    2. The task given looks like just an one-off query, for which I don't thing you need to over engineer solution.

    Wow, that's a STUNNINGLY HUGE!!!! change from your responses here:

    http://qa.sqlservercentral.com/Forums/Topic936326-338-1.aspx?Highlight=studid

    And that was an actual ONE-TIME situation.

    This q looks likely to be an on-going situation.

    Scott Pletcher, SQL Server MVP 2008-2010

  • (edit: This is in response to Euguene.)

    I think you're being a bit tongue-in-cheek, but still ...

    Part of the thing that makes this site such a good resource is the number of experienced professionals who engage in the discussion to the point that provided solutions aren't just ok, but they're solid and thoughtful. If you think using a tally table is "over-engineering" I would have to disagree with you strenuously. The use of tally tables should be a pretty regular occurrence for anyone who writes highly optimized T-SQL code.

    Now it may be that this is a one-off. It may be that the OP wanted a quick pivot. But since those ideas were not expressed but merely assumed, I think it's better to offer a more optimized solution. If readers choose to take a "simpler path" that's fine.

    └> bt



    Forum Etiquette: How to post data/code on a forum to get the best help[/url]

  • Thank you both for the solution.

    Actual requirement is I need to find Start Date and End Date difference between these 2 dates and see which year it will fall each item.

    3 examples.

    ITEMNo of Days

    1 485

    2 364

    3 1051

    1st item will fall in 2006 & 2007 year

    2nd item will fall in only 2006 year because it is year or less than year.

    3rd item will fall in 2006, 2007 & 2008

    Any suggestions will be greatly helpful.

    CREATE TABLE [dbo].[T1](

    [ITEM] [char](15) NOT NULL,

    [STRTDATE] [datetime] NOT NULL,

    [ENDDATE] [datetime] NOT NULL

    )

    INSERT INTO T1

    SELECT '1', '2006-01-01', '2007-05-01'

    INSERT INTO T1

    SELECT '2', '2006-04-01', '2007-03-31'

    INSERT INTO T1

    SELECT '3', '2006-04-01', '2009-02-15'

    SELECT ITEM, DATEDIFF(DAY, STRTDATE, ENDDATE) FROM T1

Viewing 10 posts - 1 through 9 (of 9 total)

You must be logged in to reply to this topic. Login to reply