2010-12-23 8 views
1

Ich habe eine SQL-Tabelle der Verkaufsdaten (wie die unten), wie kann ich eine Ergebnismenge generieren, die die Zwischensummen einbezieht und die Ergebnisse idealerweise in absteigender Reihenfolge des höchstbezahlten Kunden sortiert?Zwischensummen und SQL

So eine Tabelle wie die Folgenden angegeben:

CUS_ID | PRODUCT | AMOUNT 
12  | A  | 2.50 
12  | B  | 5.80 
24  | A  | 10.00 
24  | B  | 30.00 

Ich würde folgendes Ergebnis:

CUS_ID | Product | AMOUNT 
24  | A  | 10.00 
24  | B  | 30.00 
24  | Total | 30.00 
12  | A  | 2.50 
12  | B  | 5.00 
12  | Total | 7.50 

Bisher kann ich mit der folgenden Abfrage kommen:

SELECT cus_id, product, amount FROM Sales 
UNION ALL 
    (SELECT cus_id, 'ZZZZ' AS product, SUM(amount) FROM Sales GROUP BY cus_id) 
ORDER BY cus_id, product 

Die Abfrage verwendet jedoch "ZZZZ" anstelle von "Total" (was durch Suchen und Ersetzen nachträglich behoben werden kann), tut dies jedoch nicht in der Reihenfolge der Menge sortieren.

BEARBEITEN: Bitte zögern Sie nicht, Antworten zu posten, die sich nicht mit der Sortierung befassen. Einige der Antworten waren mir sehr hilfreich.

+0

Aber warum fügen Sie die "Summe" in dasselbe Ergebnis ein wie die "Umsatz" -Daten? Die Datenbank ist kein Datenpräsentationstool und ein Produkt namens "Total" macht keinen Sinn. Warum nicht zwei getrennte Abfragen haben - eine für die Verkaufsdaten und eine für die Summen? –

+0

@Kirk, ein Client erwartet dieses Format in einem Verkaufsbericht (außer bei vielen Metriken außer Betrag). Während die Formatspezifikation eine harte Anforderung zu sein scheint, wollte ich so viel in SQL arbeiten, bevor ich meinen eigenen Code einbringe – notnoop

Antwort

5

Werfen Sie einen Blick auf etwas wie

DECLARE @Sales TABLE(
     CUS_ID INT, 
     PRODUCT VARCHAR(20), 
     AMOUNT FLOAT 
) 
INSERT INTO @Sales SELECT 12,'A', 2.50 
INSERT INTO @Sales SELECT 12,'B', 5.80 
INSERT INTO @Sales SELECT 24,'A', 10.00 
INSERT INTO @Sales SELECT 24,'B', 30.00 

;WITH Vals AS (
     SELECT cus_id, 
       product, 
       amount, 
       1 DisplayOrder, 
       SUM(amount) OVER(PARTITION BY cus_id) OrderTotal 
     FROM @Sales 
     UNION ALL 
     SELECT cus_id, 
       'Total' AS product, 
       SUM(amount), 
       2 DisplayOrder, 
       SUM(amount) 
     FROM @Sales 
     GROUP BY cus_id 
) 
SELECT cus_id, 
     product, 
     amount 
FROM Vals 
ORDER BY OrderTotal DESC,cus_id,DisplayOrder, product 
4

Wie Sie glücklich sind hier nicht zu haben, das Sortieren eine schnelle Reaktion ist, bevor ich wieder an die Arbeit. Es gibt eine fantastische Reporting-Funktion in SQL-Server - Mit Rollup. Es fügt einer Abfrage automatisch Zwischen- und Summenzeilen hinzu; basierend auf den Gruppierungen, die Sie verwenden.

Als sehr schnelles Beispiel mit Tabellendefinition des @ Astander

DECLARE @Sales TABLE(
      CUS_ID INT, 
      PRODUCT VARCHAR(20), 
      AMOUNT FLOAT 
    ) 
    INSERT INTO @Sales SELECT 12,'A', 2.50 
    INSERT INTO @Sales SELECT 12,'B', 5.80 
    INSERT INTO @Sales SELECT 24,'A', 10.00 
    INSERT INTO @Sales SELECT 24,'B', 30.00 

Select Cus_ID, Product, SUM(Amount) 
From @Sales 
group by cus_id, product with rollup 

Das gibt

Cus_ID  Product    
----------- -------------------- ---------------------- 
12   A     2.5 
12   B     5.8 
12   NULL     8.3 
24   A     10 
24   B     30 
24   NULL     40 
NULL  NULL     48.3 

Um es einfacher zu machen Ihren Berichtsdatenextrakt zu schreiben und die Zwischensummenzeilen identifiziert eine Funktion gibt es - Gruppierung - die Sie nach Elementen gruppieren können. Im folgenden Beispiel werden Zwischen- und Summenzeilen identifiziert.

DECLARE @Sales TABLE(
     CUS_ID INT, 
     PRODUCT VARCHAR(20), 
     AMOUNT FLOAT 
) 
INSERT INTO @Sales SELECT 12,'A', 2.50 
INSERT INTO @Sales SELECT 12,'B', 5.80 
INSERT INTO @Sales SELECT 24,'A', 10.00 
INSERT INTO @Sales SELECT 24,'B', 30.00 

select 
    case 
     when GROUPING(product) = 1 and GROUPING(cus_id) = 0 then 'Sub Total - Customer -' + cast(Cus_ID as varchar(10)) 
     when GROUPING(product) = 1 and GROUPING(cus_id) = 1 then 'Total' 
     else cast(Cus_ID as varchar(10)) end as Cus_ID, 
     PRODUCT, 
    sum(Amount) as Total_Amount 
From @sales 
group by cus_id, product with rollup 

Rückkehr

Cus_ID       PRODUCT    Total_Amount 
-------------------------------- -------------------- ---------------------- 
12        A     2.5 
12        B     5.8 
Sub Total - Customer -12   NULL     8.3 
24        A     10 
24        B     30 
Sub Total - Customer -24   NULL     40 
Total       NULL     48.3 

Eine leichte zwicken wird es die Sortierung Sie sind nach dem zu tun bekommen.