2

次の SQL ステートメントを検討してください。

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)

結果が正しく生成されます。

2012, 0, 89.00
2011, 0, 230.00
2010, 0, 450.0

ただし、別の顧客が 2011 年だけに注文した場合は、他の 2 つの行を生成する必要があります (値は 0 ですが)。

2011, 0, 230.00
2012, 0, 0
2010, 0, 0

これを正しく行うにはどうすればよいですか?レポートは過去 3 年間に生成されることに注意してください。

4回目の更新 提案どおりにコードを変更しました:

DECLARE @CustomerId INT = 48;
DECLARE @CurrentYear INT = YEAR(GETDATE());

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

これにより、次のような結果セットが生成されます (私はそれを確認し、これが事実であることを確認しました)。

2012
2011
2010

次に、次のようにテーブルを結合 (RIGHT JOIN) します。

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

ただし、顧客がまだ注文していないことを考慮してください。したがって、これは 0 の値を持つ 3 つの行を生成する必要があります。ただし、提案されたこれらのソリューションはどれもこれを行いません。

FINAL UPDATE [解決済み]: where 句により、これらの行が最終結果セットに含まれなくなりました。したがって、Darvin が示唆したように、WHERE 句を AND に置き換えただけで、問題は解決しました。

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
4

2 に答える 2

1

サンプルコードをフィドルで書きました。http://sqlfiddle.com/#!3/eddfe/9/0お役に立てば幸いです。

アイデアは、すべての年でUDFを作成してから、そのテーブルへの外部結合を行うことです。

于 2012-06-13T11:39:14.797 に答える
0

次はどうですか:

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 
于 2012-06-13T11:37:33.320 に答える