我在这一行的表达式上遇到了麻烦
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
答案 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。
还有一些其他提示:
说清楚你的意思。为什么在键入yyyy
并更明确时键入YEAR
?要知道为什么这很重要,试着猜测它会返回什么,然后试着弄清楚为什么它不符合你的想法:
SELECT DATEPART(y, GETDATE());
您的语法不正确。你不能说CASE WHEN (some boolean expression) THEN
- 你必须将它与某些东西进行比较。 CASE
不是布尔构造,它是一个返回单个结果的表达式。因此,您必须对其进行评估,例如CASE WHEN (expression) = 1 THEN
...
请不要将AS 'alias'
语法与单引号一起使用。 When delimiters are necessary (they're not in this case), use [square brackets]
。不推荐使用某些形式的别名单引号分隔符,它们使代码更难阅读,因为它们看起来像字符串文字。
请阅读以下有关日期范围查询的文章:
答案 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))