2011-07-05 7 views
6

Chcę zapytać o tabelę zamówień i pokazać identyfikator klienta oraz sumę wszystkich jego zamówień, jednak zamówienia mogą mieć dodatnie lub ujemne sumy.Zapytanie o agregację SQL dla SUM, ale zezwalaj tylko na sumy dodatnie (w przeciwnym razie 0)

select customer_id, SUM(order_total) from orders group by customer_id; 

Teraz moje pytanie - w jaki sposób można osiągnąć następujące w jednej sql zapytanie:

Jeżeli suma jest dodatnia, chcę wyświetlić go jak jest; jeśli suma jest ujemna, chcę wyświetlić 0 zamiast faktycznej kwoty.

To, czego szukam, to funkcja, która może sobie z tym poradzić, podobna do funkcji IFNULL (IFNULL(SUM(order_total),0)), ale zamiast sprawdzania wartości NULL, powinna sprawdzić wynik ujemny.

Pseudo kod:

IFNEGATIVE(SUM(order_total),0) 

Czy istnieje prosty sposób w standardzie SQL (lub specjalnie w MySQL 5.5, byłoby również ok).

Odpowiedz

10
SELECT customer_id, 
    CASE 
    WHEN SUM(order_total) < 0 THEN 0 
    ELSE SUM(order_total) 
    END 
    FROM orders 
    GROUP BY customer_id; 

Sprawdź swój plan wykonania, ale 2 SUM s prawdopodobnie zostanie zoptymalizowany do pojedynczy pod maską SUM.

+0

Wielkie dzięki, nie użyłem przypadków w sql często, dobrze wiedzieć :) Myślę, że niektóre z innych udzielonych odpowiedzi (tj. JEDNA także praca), jednak niech akceptuję tutaj ten głos, awansuję także pozostałe. –

1

jeśli mogę zrozumieć jej tylko owinąć go GREATEST

SELECT customer_id, GREATEST(0,SUM(order_total)) 
FROM orders GROUP BY customer_id; 

spojrzenia na link

+0

To sumuje tylko zamówienia dodatkowe. OP prosi o sumę wszystkich zamówień. –

+0

aktualizuję moją odpowiedź, teraz rozumiem, czego on potrzebuje –

1

Nie możesz użyć instrukcji CASE?

Coś jak:

CASE WHEN [Field] < 0 THEN 0 

Albo ja czegoś brakuje?

+0

coś przeoczyłeś.jest to * suma *, która nie powinna być ujemna - poszczególne wiersze mogą być mieszane + ve i -ve, o ile suma nie jest ujemna – Bohemian

+0

prawie wydawało się to zbyt proste! Dzięki. – CatchingMonkey

3

nie testowano, ale coś takiego powinien zrobić:

SELECT customer_id , IF(SUM(order_total) > 0, SUM(order_total), 0) AS sum FROM orders GROUP BY customer_id 
-2

Aby wyświetlać tylko pozytywne użytkowy mający tak:

select customer_id, SUM(order_total) from orders group by customer_id HAVING SUM(order_total) > 0; 

W przeciwnym przypadku użycia wymienionych gdzie indziej tutaj

+0

To ograniczy jego wyszukiwanie, ale nie wyświetli 0, gdy suma będzie ujemna. – Vache

+0

Zrealizowany źle zrozumiał "zero wyświetlacza", ale zostawił tu odpowiedź na inne przypadki ... –

8

Spróbuj z :

select customer_id, GREATEST(SUM(order_total),0) from orders group by customer_id; 
+1

+1 lubię to - tylko suma raz – Bohemian

+1

Podoba mi się to również lepiej dla czytelności/łatwości konserwacji, ale to szybkie sprawdzenie mój koniec dla podobnego scenariusza pokazuje ten sam plan wykonania w SQL 2012 - serwer SQL może zorientować się, że naprawdę potrzebujesz go tylko raz. –

+1

I zdaję sobie sprawę, że jest to stare pytanie i po prostu zauważyłem, że tak naprawdę jest to dla MySQL, ale wygląda na to, że optymalizacja jest bardzo niska. Założę się, że MySQL też może to zrobić. –

0
select Id,case when (sum(amount)<0) then 0 else sum(amount) end from tblsum group by Id 
0

Możesz także spróbować;

+0

nie powinno być (suma (fld) + suma (abs ((fld)))/2 –