SSRS - 月未在正确的日期开始
SSRS - Month not starting on correct day
我正在尝试制作一个报告,为每个月生成一个日历,用户可以在其中指定月份和年份的范围。我的矩阵在 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
当前查询结果(注意WeekDay
以2开头的为8月):
基于 this article.
--更新--
我在下面的查询中使用 CTE 来获取我需要填写此日历的额外日期。我在日期 table 测试了它,明天将用最终查询更新我的答案:
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;
8 月 1 日是星期一,所以工作日应该是 1。但在您的 table
中是 2
您可以将日期分组到矩阵中以获得正确的布局。
插入一个矩阵。按工作日(数字)对列进行分组和排序。按周数对行进行分组和排序。它应该是这样的:
现在当你 运行 它会像这样出现:
最终答案:
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;
我正在尝试制作一个报告,为每个月生成一个日历,用户可以在其中指定月份和年份的范围。我的矩阵在 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
当前查询结果(注意WeekDay
以2开头的为8月):
基于 this article.
--更新--
我在下面的查询中使用 CTE 来获取我需要填写此日历的额外日期。我在日期 table 测试了它,明天将用最终查询更新我的答案:
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;
8 月 1 日是星期一,所以工作日应该是 1。但在您的 table
中是 2您可以将日期分组到矩阵中以获得正确的布局。
插入一个矩阵。按工作日(数字)对列进行分组和排序。按周数对行进行分组和排序。它应该是这样的:
现在当你 运行 它会像这样出现:
最终答案:
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;