这个问题与此有关,看不到任何解决方案:here
我有一张桌子向我展示了一个区域的所有会话。
此会话有一个开始日期。
我需要按特定区域(在本例中)获取会话开始日期的所有日期
我有这个问题:
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 |
我想要这样的事情:
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 |
在这种情况下,该表会在1月份的所有日期返回。
第二列是当天发生的会话数,因为同一天可能会有多个会话。
任何人都可以帮助我?
答案 0 :(得分:4)
请尝试:
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
答案 1 :(得分:3)
这将有效:
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
它使用master..spt_values
表上的简单连接来生成行。
答案 2 :(得分:1)
只是日历表的一个例子。要返回一个月的数据,请调整&lt;之间的天数。 32,一年到365 + 1。您可以使用查询计算一个月内或开始/结束日期之间的天数。我不知道如何在SQL Server中执行此操作。我正在使用硬编码值来显示2013年1月的所有日期。您可以调整差异的开始和结束日期。月份或获取查询的开始/结束日期......:
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