Sql 5个月前出示where条款

Sql 5个月前出示where条款,sql,sql-server,sql-server-2008,Sql,Sql Server,Sql Server 2008,我在这行的这个case表达式上遇到了问题 DATEPART(yyyy, DATEADD(mm, -5, getdate())) 如果我删除这一行,效果很好,但如果我不删除它,它会从每个12月选择记录,而不仅仅是像我希望的那样从2012年12月开始 我到处都找遍了,找不出来 Select C.CustId , Sum(Case DATEPART(mm, I.InvoiceDate) When DATEPART(mm, DATEADD(mm, -5, getdate())) and DA

我在这行的这个case表达式上遇到了问题

DATEPART(yyyy, DATEADD(mm, -5, getdate()))
如果我删除这一行,效果很好,但如果我不删除它,它会从每个12月选择记录,而不仅仅是像我希望的那样从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

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

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

我想你可能想要

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;
嗯,为什么不:

WHERE InvoiceDate >= DATEADD(MONTH, DATEDIFF(MONTH,0,GETDATE())-4, 0)
  AND InvoiceDate <  DATEADD(MONTH, DATEDIFF(MONTH,0,GETDATE())-3, 0)
不管怎样,现在您实际上有机会在
InvoiceDate
上使用索引,而不是这个
DATEPART(MONTH
hack),这是不可销售的

还有一些其他提示:

  • 请详细说明您的意思。当您可以键入
    YEAR
    并更加明确时,为什么要键入
    yyy
    ?若要了解这一点的重要性,请尝试猜测它将返回什么,然后尝试找出它为什么不执行您认为的操作:

    SELECT DATEPART(y, GETDATE());
    
  • 你的语法不正确。你不能说
    CASE WHEN(某个布尔表达式)然后
    -你必须将它与某个东西进行比较。
    CASE
    不是布尔构造,它是一个返回单个结果的表达式。所以你必须对它求值,比如
    CASE WHEN(表达式)=1然后

  • 请不要将
    用作带有单引号的“别名”
    语法。不推荐使用某些形式的别名单引号分隔符,它们使代码更难阅读,因为它们看起来像字符串文字

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


    试试这个。它会为您提供当月的所有动态记录-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))
    

    您在哪个RDBMS上运行此查询?为什么用MySQL、SQL Server和sqlite标记您的问题?这可能会在一千年中产生结果。您希望实现什么?DATEPART(mm,DATEADD(mm,-5,getdate())=12和…=2012???当X=Y和Z=Y中有一个条件时,就有X和Z。我只想返回5个月前的记录,而不必像这样声明年份选择…从…开始,其中年份(getdate())=2012和月份(getdate())=12我需要它是动态的,以便在2014年4月返回2013年12月的记录
    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;
    
    SELECT DATEPART(y, GETDATE());
    
    select ... FROM ... where YEAR(your_timestamp) = YEAR(DATE_SUB(NOW(), INTERVAL 5 MONTH)) AND MONTH(your_timestamp) = Month(DATE_SUB(NOW(), INTERVAL 5 MONTH))