简体   繁体   中英

Query to return all the days of a month

This problem is related to this, which has no solution in sight: here

I have a table that shows me all sessions of an area.

This session has a start date.

I need to get all the days of month of the start date of the session by specific area (in this case)

I have this query:

SELECT idArea, idSession, startDate FROM SessionsPerArea WHERE idArea = 1

idArea | idSession |  startDate  |
   1   |    1      |  01-01-2013 |
   1   |    2      |  04-01-2013 |
   1   |    3      |  07-02-2013 |

And i want something like this:

    date     |  Session    |
01-01-2013   |    1        |
02-01-2013   |    NULL     |
03-01-2013   |    NULL     |
04-01-2013   |    1        |
........     |             |
29-01-2013   |   NULL      |
30-01-2013   |   NULL      |

In this case, the table returns me all the days of January.

The second column is the number of sessions that occur on that day, because there may be several sessions on the same day.

Anyone can help me?

Please try:

DECLARE @SessionsPerArea TABLE (idArea INT, idSession INT, startDate DATEtime)
INSERT  @SessionsPerArea VALUES (1,1,'2013-01-01')
INSERT  @SessionsPerArea VALUES (1,2,'2013-01-04')
INSERT  @SessionsPerArea VALUES (1,3,'2013-07-02')

DECLARE @RepMonth as datetime
SET @RepMonth = '01/01/2013';
WITH DayList (DayDate) AS
(
    SELECT @RepMonth
    UNION ALL
    SELECT DATEADD(d, 1, DayDate)
    FROM DayList
    WHERE (DayDate < DATEADD(d, -1, DATEADD(m, 1, @RepMonth)))
)
SELECT *
FROM DayList t1 left join @SessionsPerArea t2 on t1.DayDate=startDate and t2.idArea = 1

This will work:

DECLARE @SessionsPerArea TABLE (idArea INT, idSession INT, startDate DATE)
INSERT  @SessionsPerArea VALUES
(1,1,'2013-01-01'),
(1,2,'2013-01-04'),
(1,3,'2013-07-02')

;WITH t1 AS 
(
    SELECT  startDate
            , DATEADD(MONTH, DATEDIFF(MONTH, '1900-01-01', startDate), '1900-01-01') firstInMonth
            , DATEADD(DAY, -1, DATEADD(MONTH, DATEDIFF(MONTH, '1900-01-01', startDate) + 1, '1900-01-01')) lastInMonth
            , COUNT(*) cnt
    FROM    @SessionsPerArea
    WHERE   idArea = 1
    GROUP BY
            startDate
)
, calendar AS
(
    SELECT  DISTINCT DATEADD(DAY, c.number, t1.firstInMonth) d
    FROM    t1 
    JOIN    master..spt_values c ON
            type = 'P'
    AND     DATEADD(DAY, c.number, t1.firstInMonth) BETWEEN t1.firstInMonth AND t1.lastInMonth
)

SELECT  d date
        , cnt Session
FROM    calendar c
LEFT    JOIN t1 ON t1.startDate = c.d

It uses simple join on master..spt_values table to generate rows.

Just an example of calendar table. To return data for a month adjust the number of days between < 32, for a year to 365+1. You can calculate the number of days in a month or between start/end dates with query. I'm not sure how to do this in SQL Server. I'm using hardcoded values to display all dates in Jan-2013. You can adjust start and end dates for diff. month or to get start/end dates with queries...:

WITH data(r, start_date) AS 
(
 SELECT 1 r, date '2012-12-31' start_date FROM any_table --dual in Oracle
  UNION ALL
 SELECT r+1, date '2013-01-01'+r-1 FROM data WHERE r < 32 -- number of days between start and end date+1
)
 SELECT start_date FROM data WHERE r > 1
/

START_DATE
----------
1/1/2013
1/2/2013
1/3/2013
...
...
1/31/2013

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM