生产5个月前的where子句

时间:2013-04-05 12:53:53

标签: sql sql-server sql-server-2008

我在这一行的表达式上遇到了麻烦

DATEPART(yyyy, DATEADD(mm, -5, getdate()))

如果我删除这一行它可以正常工作,但是如果我将其删除,它会从每个Decemeber中选择记录,而不仅仅是我想要的2012年12月。

我到处搜寻,我无法弄明白。

Select C.CustId ,
Sum(Case DATEPART(mm, I.InvoiceDate)
When DATEPART(mm, DATEADD(mm, -5, getdate())) and
     DATEPART(yyyy, DATEADD(mm, -5, getdate()))
  Then Ia.Amount 
  Else 0 End) As 'Total0'
from Invoice I 
inner join InvoiceAmtSummary Ia  on I.GUIDInvoice=Ia.GUIDInvoice
inner join Customer C on  C.GUIDCustomer=I.GUIDCustomer
group by C.CustId

4 个答案:

答案 0 :(得分:1)

我想你可能想要

SELECT
            C.CustId,
            SUM
            (
                CASE 
                    WHEN
      DATEPART(mm, I.InvoiceDate) = DATEPART(mm, DATEADD(mm, -5, getdate()))
  AND
      DATEPART(yyyy, I.InvoiceDate) = DATEPART(yyyy, DATEADD(mm, -5, getdate()))
                        THEN Ia.Amount
                    ELSE
                        0
                END
            ) [Total0]
    FROM 
            Invoice I 
        JOIN
            InvoiceAmtSummary Ia  
                ON I.GUIDInvoice = Ia.GUIDInvoice
        JOIN
            Customer C 
                ON  C.GUIDCustomer = I.GUIDCustomer
    GROUP BY
            C.CustId

或者,更明智地

DECLARE @TargetDate DateTime;
DECLARE @TargetYear Int;
DECLARE @TargetMonth Month;

SET @TagetDate = DATEADD(mm, -5, getdate()));
SET @TargetYear = YEAR(@TargetDate);
SET @TargetMonth = MONTH(@TargetDate);

SELECT
            C.CustId,
            SUM(COALESCE(Ia.Amount, 0))
     FROM
            Customer C
         LEFT JOIN
            ( 
            SELECT
                         MONTH(I.InvoiceDate) Month,
                         YEAR(I.InvoiceYear) Year,
                         I.GUIDInvoice,
                         I.GUIDCustomer
                FROM
                         Invoice I
            ) S
                ON S.GUIDCustomer = C.GUIDCustomer
         LEFT JOIN
            InvoiceAmtSummary Ia
                ON Ia.GUIDInvoice = S.GUIDInvoice
     WHERE
             S.Year = @TargetYear
         AND
             S.Month = @TargetMonth
     GROUP BY
             C.CustID;

答案 1 :(得分:1)

呃,为什么不呢:

WHERE InvoiceDate >= DATEADD(MONTH, DATEDIFF(MONTH,0,GETDATE())-4, 0)
  AND InvoiceDate <  DATEADD(MONTH, DATEDIFF(MONTH,0,GETDATE())-3, 0)

最终评估(今天,2013年4月5日):

WHERE InvoiceDate >= '2012-12-01'
  AND InvoiceDate <  '2013-01-01'

加入您的查询:

SELECT C.CustId,
  [Total0] = SUM(CASE 
    WHEN InvoiceDate >= DATEADD(MONTH, DATEDIFF(MONTH,0,GETDATE())-4, 0)
     AND InvoiceDate <  DATEADD(MONTH, DATEDIFF(MONTH,0,GETDATE())-3, 0)
    THEN Ia.Amount ELSE 0 END
  )
FROM dbo.Invoice AS I 
INNER JOIN dbo.InvoiceAmtSummary AS Ia 
   ON I.GUIDInvoice = Ia.GUIDInvoice
INNER JOIN dbo.Customer AS C 
   ON C.GUIDCustomer = I.GUIDCustomer
GROUP BY C.CustId;

虽然你可能想把它放在WHERE条款中,除非你想包括那个月没有销售的客户(似乎将它们排除在外是合乎逻辑的,因为你是已经遗漏了从未有发票的客户。 e.g。

SELECT C.CustId, Total0 = SUM(Ia.Amount)
FROM dbo.Invoice AS I
INNER JOIN dbo.InvoiceAmtSummary AS Ia 
   ON I.GUIDInvoice = Ia.GUIDInvoice
INNER JOIN dbo.Customer AS C 
   ON C.GUIDCustomer = I.GUIDCustomer
   WHERE InvoiceDate >= DATEADD(MONTH, DATEDIFF(MONTH,0,GETDATE())-4, 0)
     AND InvoiceDate <  DATEADD(MONTH, DATEDIFF(MONTH,0,GETDATE())-3, 0)
GROUP BY C.CustId;

无论如何,现在你实际上已经开始使用InvoiceDate上的索引而不是这个不可攻击的DATEPART(MONTH hack。

还有一些其他提示:

  1. 说清楚你的意思。为什么在键入yyyy并更明确时键入YEAR?要知道为什么这很重要,试着猜测它会返回什么,然后试着弄清楚为什么它不符合你的想法:

    SELECT DATEPART(y, GETDATE());
    
  2. 您的语法不正确。你不能说CASE WHEN (some boolean expression) THEN - 你必须将它与某些东西进行比较。 CASE不是布尔构造,它是一个返回单个结果的表达式。因此,您必须对其进行评估,例如CASE WHEN (expression) = 1 THEN ...

  3. 请不要将AS 'alias'语法与单引号一起使用。 When delimiters are necessary (they're not in this case), use [square brackets]。不推荐使用某些形式的别名单引号分隔符,它们使代码更难阅读,因为它们看起来像字符串文字。

  4. 请阅读以下有关日期范围查询的文章:

答案 2 :(得分:0)

要仅选择2012年12月的记录,请尝试

select ... FROM ... where YEAR(your_timestamp) = 2012 AND MONTH(your_timestamp) = 12

答案 3 :(得分:0)

试试这个。它为您提供当月的动态所有记录 - 5

select ... FROM ... where YEAR(your_timestamp) = YEAR(DATE_SUB(NOW(), INTERVAL 5 MONTH)) AND MONTH(your_timestamp) = Month(DATE_SUB(NOW(), INTERVAL 5 MONTH))