用日期过滤但保留计算

时间:2018-09-07 13:58:37

标签: sql sql-server reporting-services

我想知道在以下情况下您可以做什么:

可以说我正在过滤where子句(between eomonth(@StartDate) and eomonth(getdate()-1)中的日期。我在没有任何过滤器的情况下运行查询时,计算出的列是正确的,但问题是当我过滤说@StartDate = 06/30/2017时,计算显然会发生变化。有什么办法吗?

计算的列是一个窗口函数。

编辑:

我已经添加了数据图片。所以我正在使用窗口函数来计算agentfourmonthperiod。您将看到它对该月和前三个月的单位求和。我不想在过滤时更改它。因此,在@StartDate上进行过滤后,units和agentfourmonthperiod列应保持完全相同。请查看以下数据:

enter image description here

我想设计一个SSRS报告,该报告将在@StartDate上过滤用户,但是然后它应该像没有使用过滤器时一样显示计算结果。

希望这是有道理的。否则,我可以添加代码。它只是相当长的时间。

代码:

  WITH DATA
                AS
                (
                SELECT  
            EOMONTH(SubmissionDates.original_date_c) AS IntakeMonth,

            ProvincialArea.SAD_ProvMananger AS ProvManager,
            RegionalArea.SAD_RegMananger AS RegManager,
            SalesArea.SAD_SalesManager AS AreaSalesManager,

            ConsultantUserExt.name AS Consultant,

            COUNT(LeadsLink.LeadsID) OVER(PARTITION BY ConsultantUserExt.name, EOMONTH(SubmissionDates.original_date_c,0) ORDER BY EOMONTH(SubmissionDates.original_date_c,0)) AS Unit,
            ROW_NUMBER() OVER(PARTITION BY ConsultantUserExt.name, EOMONTH(SubmissionDates.original_date_c,0) ORDER BY EOMONTH(SubmissionDates.original_date_c,0)) AS rn

FROM Import.OobaApplication as Application

LEFT OUTER JOIN Import.OobaApplicant applicant ON application.ApplicationID = applicant.ApplicationID 
                AND applicant.PrincipleApplication = 'Y'

LEFT OUTER JOIN usr_userext_cstm ON Application.Consultant = usr_userext_cstm.comcorp_key_c
    or Application.Consultant = usr_userext_cstm.deal_maker_key_c
    or Application.Consultant = usr_userext_cstm.ops_key_c

LEFT OUTER JOIN usr_userext AS ConsultantUserExt ON usr_userext_cstm.id_c = ConsultantUserExt.id AND ConsultantUserExt.deleted = 0
LEFT OUTER JOIN usr_userext_cstm AS ConsultantUserExtCstm on ConsultantUserExt.id = ConsultantUserExtCstm.id_c

LEFT OUTER JOIN CapcubedInternalDB.dbo.ProvincialArea AS ProvincialArea ON ConsultantUserExtCstm.sad_provincialmanager_c = ProvincialArea.ID
LEFT OUTER JOIN CapcubedInternalDB.dbo.RegionalArea AS RegionalArea ON ConsultantUserExtCstm.sad_regionalmanager_c = RegionalArea.ID
LEFT OUTER JOIN CapcubedInternalDB.dbo.SalesArea AS SalesArea ON ConsultantUserExtCstm.sad_salesmanager_c = SalesArea.ID

LEFT OUTER JOIN CapcubedInternalDB.dbo.LeadsLink AS LeadsLink ON Application.ApplicationID = LeadsLink.GroupCode
LEFT OUTER JOIN suitecrmprod.dbo.leads AS SuiteLeads ON LeadsLink.LeadsID = SuiteLeads.ID

--Latest Bank Submission
LEFT OUTER JOIN (SELECT 
                    bankSub.ApplicationID As BankSubAppID, bankSub.SubmissionDate,
                    bankSub.Bank, bankSub.RequiredLoanAmount,
                    bankSub.BankCode AS BankSubBankCode

                    FROM Import.OobaBankSubmission bankSub

                    LEFT OUTER JOIN Import.OobaBankSubmission later ON bankSub.ApplicationID = later.ApplicationID
                                    AND bankSub.SubmissionDate > later.SubmissionDate
                    WHERE later.applicationID IS NULL) AS BankSub ON Application.ApplicationID = BankSub.BankSubAppID

LEFT OUTER JOIN ccrep_calendar_cstm AS SubmissionDates ON CONVERT(VARCHAR(10),BankSub.SubmissionDate,101) = SubmissionDates.original_date_c

WHERE SubmissionDates.cc_date_c BETWEEN COALESCE(EOMONTH(@StartDate), '01/31/2016') AND COALESCE(@EndDate, GETDATE(), -1)
AND ConsultantUserExtCstm.consultantstatus_c NOT LIKE 2
                )
     SELECT *
            INTO #Rn
            FROM DATA
            WHERE rn = 1

                SELECT i.IntakeMonth, c.ProvManager, c.RegManager, c.AreaSalesManager, c.Consultant, COALESCE(#Rn.Unit, 0) AS Unit
                INTO #FillData
                FROM (SELECT DISTINCT IntakeMonth FROM #Rn) AS i
                        CROSS JOIN
                    (SELECT DISTINCT Consultant, ProvManager, RegManager, AreaSalesManager FROM #Rn) AS c
                LEFT OUTER JOIN #Rn ON #Rn.IntakeMonth = i.IntakeMonth AND #Rn.Consultant = c.Consultant
                ORDER BY Consultant, IntakeMonth

                SELECT 
                    IntakeMonth,
                    Consultant,
                    Unit,
                    SUM(Unit) OVER(PARTITION BY Consultant ORDER BY Consultant ROWS BETWEEN 3 PRECEDING AND CURRENT ROW) AS agentfourmonthperiod

                FROM #FillData

                WHERE ('(All)' IN (@ProvincialManager) OR (ProvManager IN (@ProvincialManager)))
                    AND ('(All)' IN (@RegionalManager) OR (RegManager IN (@RegionalManager)))
                    AND ('(All)' IN (@AreaSalesManager) OR (AreaSalesManager IN (@AreaSalesManager)))
                    AND ('(All)' IN (@Consultant) OR (Consultant IN (@Consultant)))

                DROP TABLE #Rn
                DROP TABLE #FillData

1 个答案:

答案 0 :(得分:1)

您当然可以从查询中删除日期过滤器,并将其直接应用于报表的Tablix中。显然,这意味着SQL Server每次运行报表时都必须返回所有数据,所以我想这不是您想要的。

要使window函数有权访问前3行,您必须在计算中包括前3个月。为此,请将cte(data)中WHERE子句中的第一个条件更改为以下内容:

SubmissionDates.cc_date_c 
BETWEEN 
  ISNULL(DATEADD(month, DATEDIFF(month, 0, @StartDate)-3, 0), '01/10/2015')
AND
  ISNULL(@EndDate, DATEADD(day, DATEDIFF(day, 0, GETDATE())-1, 0))
  

由于我认为您的日期过滤器逻辑有误,因此我将其更改为包括该月的开始而不是结束。 >

现在已包括前三个月,我们可以在最后应用过滤器以从显示中排除前几个月,但这必须在之后使用窗口功能来完成,例如另一个CTE:

WITH calc AS (
    SELECT 
        IntakeMonth,
        Consultant,
        Unit,
        SUM(Unit) OVER(PARTITION BY Consultant ORDER BY Consultant ROWS BETWEEN 3 PRECEDING AND CURRENT ROW) AS agentfourmonthperiod

    FROM #FillData

    WHERE ('(All)' IN (@ProvincialManager) OR (ProvManager IN (@ProvincialManager)))
      AND ('(All)' IN (@RegionalManager) OR (RegManager IN (@RegionalManager)))
      AND ('(All)' IN (@AreaSalesManager) OR (AreaSalesManager IN (@AreaSalesManager)))
      AND ('(All)' IN (@Consultant) OR (Consultant IN (@Consultant)))
    )

SELECT IntakeMonth, Consultant, Unit, agentfourmonthperiod
FROM calc 
WHERE IntakeMonth >= ISNULL(EOMONTH(@StartDate), '01/31/2016')