我有这个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
答案 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)
后者会提供更差的性能,因此只有在日期时间
时才使用它