首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >选择年度报告的记录(过去3年)

选择年度报告的记录(过去3年)
EN

Stack Overflow用户
提问于 2012-06-13 11:17:18
回答 2查看 1.8K关注 0票数 2

考虑以下SQL语句:

代码语言:javascript
复制
DECLARE @CustomerId INT = 48;
DECLARE @CurrentYear INT = DATEPART(YEAR, GETDATE());

SELECT
    YEAR(o.OrderDate) AS Year,
    0 AS Month,
    SUM(o.GrandTotal) AS GrandTotal
FROM [Order] o
WHERE
    o.CustomerId = @CustomerId AND
    o.OrderTypeId = 4 AND
    o.IsVoid = 0 AND
    YEAR(o.OrderDate) BETWEEN @CurrentYear - 2 AND @CurrentYear
GROUP BY
    YEAR(o.OrderDate)

它正确地产生结果:

代码语言:javascript
复制
2012, 0, 89.00
2011, 0, 230.00
2010, 0, 450.0

但是,如果另一个客户仅为2011年下了订单,我需要生成这2行(尽管值为0):

代码语言:javascript
复制
2011, 0, 230.00
2012, 0, 0
2010, 0, 0

我应该怎样才能正确地做到这一点呢?请注意,这份报告将在过去三年内编写。

第4次更新I按建议修改了代码:

代码语言:javascript
复制
DECLARE @CustomerId INT = 48;
DECLARE @CurrentYear INT = YEAR(GETDATE());

DECLARE @years TABLE (
    yr INT
);
INSERT INTO @years VALUES
    (@CurrentYear),
    (@CurrentYear - 1),
    (@CurrentYear - 2)

这会产生如下结果集(我已经检查过,并确保是这样的)。

代码语言:javascript
复制
2012
2011
2010

然后,我按如下方式加入表(右联接):

代码语言:javascript
复制
SELECT
    y.yr AS Year,
    0 AS Month,
    SUM(ISNULL(o.GrandTotal, 0)) AS GrandTotal
FROM [Order] o
RIGHT JOIN @years y ON y.yr = YEAR(o.OrderDate)
WHERE
    o.CustomerId = @CustomerId AND
    o.OrderTypeId = 4 AND
    o.IsVoid = 0
GROUP BY
    y.yr

但是,考虑到客户还没有下订单,所以这需要生成3行零值。然而,所建议的解决办法中没有一个能做到这一点。

最终更新解决了where子句阻止这些行在最终结果集中的问题。因此,正如达文所建议的,我只是把WHERE子句替换为AND,问题就解决了。

代码语言:javascript
复制
SELECT
    y.yr AS Year,
    0 AS Month,
    SUM(ISNULL(o.GrandTotal, 0)) AS GrandTotal
FROM [Order] o
RIGHT JOIN @years y ON y.yr = YEAR(o.OrderDate) AND
    o.CustomerId = @CustomerId AND
    o.OrderTypeId = 4 AND
    o.IsVoid = 0
GROUP BY
    y.yr
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-06-13 11:37:33

以下几点如何?

代码语言:javascript
复制
DECLARE @CustomerId INT = 48; 
DECLARE @CurrentYear INT = DATEPART(YEAR, GETDATE());  

;with years as 
( 
SELECT YEAR(GETDATE()) as yr 
UNION ALL SELECT YEAR(DATEADD(YY,-1,GETDATE())) 
UNION ALL SELECT YEAR(DATEADD(YY,-2,GETDATE())) 
) 
SELECT      
years.yr 
,0 AS Month 
,SUM(ISNULL(o.GrandTotal,0)) AS GrandTotal  
FROM years 
LEFT OUTER JOIN Order o  
ON YEAR(o.OrderDate) = years.yr 
AND o.customerid = @customerid
AND     o.OrderTypeId = 4  
AND     o.IsVoid = 0  
GROUP BY      
years.yr 
票数 0
EN

Stack Overflow用户

发布于 2012-06-13 11:39:14

我用小提琴写了示例代码。希望http://sqlfiddle.com/#!3/eddfe/9/0能帮上忙。

这样做的想法是创建一个包含所有年份的UDF,然后对该表执行外部连接。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/11013725

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档