古典的なtop-n-per-group
の問題です。ここでは、top
だけでなく、グループごとにbottom
という値を取得する必要があります。
セルフジョインなしで達成するための標準的な方法の1つは、ROW_NUMBER
です。あなたの場合、昇順と降順の2つの数字セットがあります。それが実行柱の仕組みを理解するには
サンプルデータ
DECLARE @T TABLE (location int, dt date, Amount int);
INSERT INTO @T (location, dt, Amount) VALUES
(1000,'2016-01-01',400),
(1000,'2016-01-04',600),
(1000,'2016-01-05',650),
(1000,'2016-01-06',820),
(1000,'2016-01-18',850),
(1000,'2016-01-22',900),
(1000,'2016-01-28',910),
(1000,'2016-01-31',950),
(2000,'2016-01-07',100),
(2000,'2016-01-13',150),
(2000,'2016-01-15',260),
(2000,'2016-01-20',330);
クエリ
WITH
CTE
AS
(
SELECT
location
,dt
,Amount
,ROW_NUMBER() OVER (PARTITION BY location ORDER BY dt ASC) AS rnAsc
,ROW_NUMBER() OVER (PARTITION BY location ORDER BY dt DESC) AS rnDesc
FROM @T
)
SELECT
location
,SUM(CASE WHEN rnAsc = 1 THEN -Amount ELSE Amount END) AS diff
FROM CTE
WHERE
rnAsc = 1
OR rnDesc = 1
GROUP BY location
ORDER BY location;
結果
+----------+------+
| location | diff |
+----------+------+
| 1000 | 550 |
| 2000 | 230 |
+----------+------+
最初にCTE内でクエリを実行し、中間結果を調べます。
メインクエリは単にlocation
でグループ化し、2つの値のSUM
を計算します。 CASE
式は、最初の値の符号を変更して差分を取得します。
1つの行だけの位置を持つことができる場合、結果は負の値Amount
になります。あたかも0と唯一の利用可能なAmount
値の間の差であるかのように。この場合、他の結果を得たい場合は、質問を明確にしてください。以下は
HTTPです。 com/questions/285551 /なぜ私がアップロードできないのかをコードで確認するときの質問の画像/ 285557#28555 7 –