Якщо позитивно, підсумуйте всі елементи. Якщо негативний, поверніть кожен


28

Мені потрібно знайти шлях до SUM()всіх позитивних значень для numі повернути SUM()всі додатні числа та окремий рядок для кожного від’ємного числа. Нижче наведено зразок 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)

І це мій бажаний результат (позитивні цифри для кожного продавця 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;

Якщо ви хочете обидва sumзначення в одному рядку, тоді ви повинні створити функцію maxValueminValue) і використовувати це як sum(maxValue(0, num))і sum(minValue(0, num)). Це описано в: Чи існує функція Max у SQL Server, яка приймає два значення, наприклад, Math.Max ​​у .NET?


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 0. salesid ELSE salesid+id+1працювали б також
  • 0 вважається позитивним числом, звідси >= 0( нульовий позитивний чи негативний? ). Хоча x+0=xздається, що =знак робить непотрібним, це допомагає пам’ятати, що цей випадок не забутий і як обробляється 0 (як SUM або як окремий рядок). Якщо 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) Класний запит.
користувач2023861

1
Так, але ОП повинен був спочатку встановити SQL Server 2012. IIF починається з SQL Server 2012: msdn.microsoft.com/en-us/library/hh213574.aspx . OP позначила своє запитання на SQL Server 2008.
Жульєн Вавассер
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.