每日报告与存储过程

时间:2017-05-22 10:11:08

标签: sql-server tsql stored-procedures

我有这个sp来制作一份需要每天报道的报道。我该如何实施日期部分?就像我写的那样,或者这是一些简单的方法吗?!

ALTER PROCEDURE [dbo].[pr_Report]
    @YearOfRegistration INT
AS 
    SELECT
        peCountryID,
        peCountryName as coName,
        ISNULL(SUM(CASE WHEN peIsSubmittedFL = 1 THEN 1 ELSE 0 END ),0) AS rdValue1,
        ISNULL(SUM(CASE WHEN peIsSubmittedFL = 0 THEN 1 ELSE 0 END ),0) AS  rdValue2,
        COUNT(*) AS Total
    FROM 
        vPerson
    WHERE 
        @YearOfRegistration = 0 
        OR peYearOfRegistration = @YearOfRegistration
        AND (DATEPART(dd, peSubmitDate) = DATEPART(dd, GETDATE()) 
        AND DATEPART(MM, peSubmitDate) = DATEPART(MM, GETDATE()) 
        AND DATEPART(yy, peSubmitDate) = DATEPART(YY, GETDATE()))
    GROUP BY 
        peCountryofResidencyID, peCountryOfResidencyName

2 个答案:

答案 0 :(得分:1)

逻辑是正确的,但这是一个非常糟糕的方法。尽可能避免在数据上调用函数,尤其是在where子句中,因为这意味着不能使用基础列上的任何索引。

你的谓词最好写成:

WHERE   peSubmitDate >= CAST(GETDATE() AS DATE)
AND     peSubmitDate < DATEADD(DAY, 1, CAST(GETDATE() AS DATE));

这种方式可以使用索引,您的查询是sargable

碰巧,将DATETIME转换为DATE(反之亦然)实际上是不使用函数规则的例外,因此您可以将其缩短为:

WHERE   CONVERT(DATE, peSubmitDate) = CONVERT(DATE, GETDATE())

另一点是,尽管使用OR来适应您的选项(按年度过滤或返回所有记录)可能看起来更好,但您会发现有两个单独的查询会表现得更好。所以你的最终SP可能是:

ALTER PROC [dbo].[pr_Report] @YearOfRegistration INT
AS
BEGIN
    IF (@YearOfRegistration = 0)
    BEGIN
        SELECT  peCountryID,
                peCountryName as coName,
                ISNULL(SUM(CASE WHEN peIsSubmittedFL = 1 THEN 1 ELSE 0 END ),0) AS rdValue1,
                ISNULL(SUM(CASE WHEN peIsSubmittedFL = 0 THEN 1 ELSE 0 END ),0) AS  rdValue2,
                COUNT(*) AS Total
        FROM    vPerson
        WHERE   CONVERT(DATE, peSubmitDate) = CONVERT(DATE, GETDATE())  
        GROUP BY peCountryofResidencyID,peCountryOfResidencyName
    END
    ELSE
    BEGIN
        SELECT  peCountryID,
                peCountryName as coName,
                ISNULL(SUM(CASE WHEN peIsSubmittedFL = 1 THEN 1 ELSE 0 END ),0) AS rdValue1,
                ISNULL(SUM(CASE WHEN peIsSubmittedFL = 0 THEN 1 ELSE 0 END ),0) AS  rdValue2,
                COUNT(*) AS Total
        FROM    vPerson
        WHERE   CONVERT(DATE, peSubmitDate) = CONVERT(DATE, GETDATE())  
        AND     peYearOfRegistration = @YearOfRegistration
        GROUP BY peCountryofResidencyID,peCountryOfResidencyName;

    END
END

答案 1 :(得分:0)

getdate返回日期时间,因此如果您只想比较日期而不是时间,则可以使用强制转换。如果peSubmitDate的数据类型为Date,请使用此比较:

peSubmitDate  = cast(GetDate() as date)

如果是数据时间,那么就像这样使用它:     cast(peSubmitDate as date)= cast(GetDate()as date)

后者会提供更差的性能,因此只有在日期时间

时才使用它