正の場合、すべてのアイテムを合計します。負の場合、それぞれを返します


28

SUM()すべての正の値のすべての正の値への方法を見つけnumSUM()、すべての正の数と各負の数の個別の行を返す必要があります。以下にサンプルDDLを示します。

Create Table #Be
(
    id int
    , salesid int
    , num decimal(16,4)
)

Insert Into #BE Values
    (1, 1, 12.32), (2, 1, -13.00), (3, 1, 14.00)
    , (4, 2, 12.12), (5, 2, 14.00), (6, 2, 21.23)
    , (7, 3, -12.32), (8,3, -43.23), (9, 3, -2.32)

そして、これは私の希望する出力です(各salesidの正の数値SUM()と負の数値は個別の行を返します):

salesid    num
1          26.32
1          -13.00
2          47.35
3          -12.32
3          -43.23
3          -2.32

回答:


26

これを試して:

SELECT   salesid, sum(num) as num
FROM     #BE
WHERE    num > 0
GROUP BY salesid
UNION ALL
SELECT   salesid, num
FROM     #BE
WHERE    num < 0;

sum1つの行に両方の値が必要な場合は、maxValue(and minValue)関数を作成し、これをsum(maxValue(0, num))and として使用する必要がありますsum(minValue(0, num))。これについては、SQL Serverに.NETのMath.Maxのような2つの値を取るMax関数はありますか?


8
クエリを修正しました。UNION ALL同様に必要でしたUNION
ypercubeᵀᴹ

24

これも機能します:

SELECT salesid, SUM(num)
FROM #BE
GROUP BY salesid, CASE WHEN num >= 0 THEN 0 ELSE id END;

仮定:

  • Idは1から始まるため、を使用できますTHEN 0salesid ELSE salesid+id+1うまくいくだろう
  • 0は正数と見なされるため、>= 0ゼロは正または負ですか?x+0=x作るように見える=記号は不要、それはこの場合には忘れられていないと(SUMとして、または個々の行として)どのように0に処理されていることを覚えているのに役立ちます。the SUM() of all positive numbers意味する場合SUM of strictly positive numbers(つまり> 0)、=必要ありません。

実際のデータとインデックスを使用してテストする必要がありますが、1回のテーブルスキャンだけで、場合によってはパフォーマンスが少し向上することがあります。

インデックスがない場合、以下のテストデータに対するこのクエリの影響は小さいようです。

SET NO COUNT ON
Create Table #Be(
  id int identity(0,1)
  ,salesid int,num decimal(16,4)
)
INSERT INTO #BE(salesid, num) 
SELECT CAST(rand()*10 as int), rand() - rand()
GO 10000 -- or 100.000

次のようなiifを使用すると、グループ句を単純化できGROUP BY salesid, iif(num >= 0, 0, id) ます。クールクエリ。
user2023861

1
はい。ただし、OPは最初にSQL Server 2012をインストールする必要があります。IIFはSQL Server 2012で開始されます:msdn.microsoft.com/en-us/library/hh213574.aspx。OPは、SQL Server 2008のと彼の質問をタグ付けしました
ジュリアンVavasseur
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.