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;