Olumluysa, tüm öğeleri toplayın. Eğer negatifse, her birini geri getirin


28

Tüm pozitif sayılar için SUM()tüm pozitif değerlerin bir yolunu bulmaya numve SUM()her pozitif sayı için ayrı bir satır döndürmeye ihtiyacım var . Aşağıda bir DDL örneği verilmiştir:

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)

Ve bu benim istediğim çıktı (her salesid için pozitif sayılar SUM()ve negatifler ayrı bir satır getirdiler ):

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

Yanıtlar:


26

Bunu dene:

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

Her iki istiyorsanız sumtek bir satırdaki değerleri o zaman bir oluşturmalısınız maxValue(ve minValue) işlevini ve olarak kullanmak sum(maxValue(0, num))ve sum(minValue(0, num)). Bu, şöyle açıklanır: SQL Server'da, .NET'teki Math.Max ​​gibi iki değer alan bir Max işlevi var mı?


8
Sorguyu düzelttim. UNION ALLAynı zamanda gerekli değil UNION.
ypercubeᵀᴹ

24

Bu da çalışır:

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

Varsayımlar:

  • Id 1'de başlar, dolayısıyla kullanabilir THEN 0. salesid ELSE salesid+id+1de işe yarar
  • 0 pozitif sayı olarak kabul edilir, bu nedenle >= 0( sıfır pozitif mi negatif mi? ). İşareti gereksiz kılıyor x+0=xgibi görünse de =, bu davanın unutulmadığını ve 0'ın nasıl kullanıldığını (bir SUM veya bireysel bir satır olarak) hatırlamaya yardımcı oluyor. Eğer the SUM() of all positive numbersaracı SUM of strictly positive numbers(yani> 0),= gerekli değildir.

Gerçek veriler ve indekslerle test edilmelidir, ancak sadece 1 tablo taramasında performans bazı durumlarda daha iyi olabilir.

Dizinin olmayışı, aşağıdaki sorgu verileri üzerinde bu sorgu ile daha küçük bir etkiye sahip gibi görünüyor:

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

Grup yan tümcesini şöyle bir iif ile sadeleştirebilirsiniz: GROUP BY salesid, iif(num >= 0, 0, id) Cool query.
user2023861

1
Evet, ancak OP ilk önce SQL Server 2012'yi kurmalıydı. IIF, SQL Server 2012 ile başlar: msdn.microsoft.com/en-us/library/hh213574.aspx . OP sorusunu SQL Server 2008 ile etiketledi.
Julien Vavasseur
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.