我正在尝试制作一个报告,为每个月生成一个日历,用户可以在其中指定月份和年份的范围。我的矩阵在Weekday
上有一个列分组,行分组在WeekNumber
上(请参阅下面的查询结果)。
我坚持的问题是,这一天是从错误的地方开始,如下所示:
这是因为我的查询仅包含该特定月份的日期,而不是之前和之后的几天,通常会在日历上显示为灰色:
虽然我怀疑这个问题也可以在矩阵本身中解决,但我不确定在查询中解决它还是在矩阵中求解它会比另一个更好。
我当前的查询:
SELECT t1.[TimeSheetLineID] ,
t1.[TimeSheetID] ,
t1.[JobID] ,
t1.[TimeSheetDate] ,
t1.[TimeSheetCreatedOn] ,
t1.[TimeSheetLastModifiedOn] ,
t1.[StartTime] ,
t1.[EndTime] ,
t1.[TotalTime] ,
t1.[EmployeeName] ,
t2.DateFull ,
t2.[FullYear] ,
t2.[WeekNumber] ,
t2.[WeekDay] ,
t2.[WeekDayName] ,
t2.[MonthDay] ,
t2.[MonthName] ,
t2.[MonthNumber]
FROM dbo.DateLookup t2
LEFT JOIN [dbo].[FactTimeSheets] t1
ON t1.TimeSheetDate = t2.DateFull
AND (t1.JobID = @jobNumber)
WHERE (t2.FullYear = @year)
AND (t2.MonthNumber BETWEEN @startMonth AND @endMonth)
ORDER BY FullYear, MonthNumber, MonthDay, WeekDay
基于this article。
- UPDATE -
我在下面的查询中使用CTE来获取填写此日历所需的额外日期。我在Date表上测试了它,并将在明天用最终查询更新我的答案:
DECLARE @year INT ,
@startMonth DATE ,
@endMonth DATE;
SET @year = '2016';
SET @startMonth = '2016-08-01';
SET @endMonth = '2016-08-31';
DECLARE @StartDate DATE ,
@EndDate DATE;
SET @StartDate = DATEADD(s, 0, DATEADD(mm, DATEDIFF(m, 0, @startMonth), 0));
SET @StartDate = DATEADD(DAY, -DATEPART(WEEKDAY, @StartDate) + 1, @StartDate);
--SELECT @StartDate
SET @EndDate = DATEADD(s, -1, DATEADD(mm, DATEDIFF(m, 0, @startMonth) + 1, 0));
SET @EndDate = DATEADD(DAY, 7 - DATEPART(WEEKDAY, @EndDate), @EndDate)
--SELECT @EndDate;
;
WITH Dates ( [Date] )
AS (
--Select First day in range
SELECT CONVERT(DATETIME, @StartDate) AS [Date]
UNION ALL
--Add a record for every day in the range
SELECT DATEADD(DAY, 1, [Date])
FROM Dates
WHERE Date < CONVERT(DATETIME, @EndDate)
),
Events
AS ( SELECT [FullYear] ,
[DateFull] ,
[WeekNumber] ,
[WeekDay] ,
[WeekDayName] ,
[MonthDay] ,
[MonthName] ,
[MonthNumber]
FROM [dbo].[DateLookup]
)
SELECT e.[FullYear] ,
e.[DateFull] ,
d.[Date] ,
e.[WeekNumber] ,
e.[WeekDay] ,
e.[WeekDayName] ,
e.[MonthDay] ,
e.[MonthName] ,
e.[MonthNumber]
FROM Dates d
LEFT JOIN Events e ON d.[Date] = CAST(e.DateFull AS DATE)
GROUP BY FullYear ,
MonthNumber ,
DateFull ,
d.[Date] ,
WeekNumber ,
MonthName ,
WeekDayName ,
MonthDay ,
WeekDay
ORDER BY Date;
- 最终更新的查询 -
我希望将来可以帮助某人。
SET @startDate = DATEADD(mm, DATEDIFF(m, 0, CAST(CAST(@year AS varchar) + '-' + CAST(@startMonth AS varchar) + '-01' AS DATETIME)), 0);
SET @startDate = DATEADD(DAY, -DATEPART(WEEKDAY, @startDate) + 1, @startDate);
SET @endDate = DATEADD(mm, DATEDIFF(m, 0, CAST(CAST(@year AS varchar) + '-' + CAST(@endMonth AS varchar) + '-01' AS DATETIME)) + 1, 0);
SET @endDate = DATEADD(DAY, 7 - DATEPART(WEEKDAY, @endDate), @endDate);
WITH Dates ( [Date] )
AS ( SELECT CONVERT(DATETIME, @startDate) AS [Date]
UNION ALL
SELECT DATEADD(DAY, 1, [Date])
FROM Dates
WHERE Date < CONVERT(DATETIME, @endDate)
),
Events
AS ( SELECT t1.[TimeSheetLineID] ,
t1.[TimeSheetID] ,
t1.[JobID] ,
t1.[TimeSheetDate] ,
t1.[TimeSheetCreatedOn] ,
t1.[TimeSheetLastModifiedOn] ,
t1.[StartTime] ,
t1.[EndTime] ,
t1.[TotalTime] ,
t1.[EmployeeName] ,
t1.[CostCategory] ,
t2.[DateFull] ,
t2.[FullYear] ,
t2.[WeekNumber] ,
t2.[WeekDay] ,
t2.[WeekDayName] ,
t2.[MonthDay] ,
t2.[MonthName] ,
t2.[MonthNumber]
FROM dbo.DateLookup t2
LEFT JOIN [dbo].[FactTimeSheets] t1 ON t1.TimeSheetDate = t2.DateFull
AND ( t1.JobID = @jobNumber )
WHERE ( t2.FullYear = @year )
)
SELECT e.[TimeSheetLineID] ,
e.[TimeSheetID] ,
e.[JobID] ,
e.[TimeSheetDate] ,
e.[TimeSheetCreatedOn] ,
e.[TimeSheetLastModifiedOn] ,
e.[StartTime] ,
e.[EndTime] ,
e.[TotalTime] ,
e.[EmployeeName] ,
e.[CostCategory] ,
e.[DateFull] ,
d.[Date] ,
e.[FullYear] ,
e.[WeekNumber] ,
e.[WeekDay] ,
e.[WeekDayName] ,
e.[MonthDay] ,
e.[MonthName] ,
e.[MonthNumber]
FROM Dates d
LEFT JOIN Events e ON d.[Date] = CAST(e.DateFull AS DATE)
ORDER BY Date;