2016-05-26 22 views
3

Angenommen, ich habe eine Tabelle, in der Kundennamen, Gerätenummern und einige Flags gespeichert sind. Einige Beispieldaten sieht ungefähr wie folgt aus:Zusammenfassen von Daten auf zwei verschiedene Arten

[CustomerName], [Device], [A], [B], [C] 
'Customer A', '1234', 1, 0, 0 
'Customer A', '1235', 1, 1, 1 
'Customer A', '1234', 1, 1, 1 
'Customer B', '1236', 1, 1, 0 
'Customer B', '1236', 1, 0, 0 
'Customer C', '1235', 1, 1, 1 

Ich brauche einen Bericht, der drei Arten von Daten stellt gleichzeitig:

  • Die Gesamtzahl der Reihen mit jeder Fahne
  • Die Anzahl der Zeilen mit jeweils flag pro Kunde
  • Die Anzahl der einzelnen Geräte, die in jeder Reihe mit jeder Fahne angezeigt

Die ersten beiden Elemente konnten relativ einfach mit ROLLUP erstellt werden, aber das letzte Element war kniffliger.

SELECT CASE WHEN (GROUPING([CustomerName]) = 1) THEN 'ALL CUSTOMERS' 
     ELSE [CustomerName] END [CustomerName], 
     COUNT(*) [Rows], 
     SUM(CAST([A] AS [int])) [A], 
     SUM(CAST([B] AS [int])) [B], 
     SUM(CAST([C] AS [int])) [C] 
    FROM [MyTable] 
GROUP BY [CustomerName] WITH ROLLUP 
UNION 
SELECT 'UNIQUE DEVICES', 
     COUNT(*), 
     SUM(CASE WHEN [A] > 0 THEN 1 ELSE 0 END), 
     SUM(CASE WHEN [B] > 0 THEN 1 ELSE 0 END), 
     SUM(CASE WHEN [C] > 0 THEN 1 ELSE 0 END) 
    FROM (
    SELECT [Device], 
      COUNT(*) [Rows], 
      SUM(CAST([A] AS [int])) [A], 
      SUM(CAST([B] AS [int])) [B], 
      SUM(CAST([C] AS [int])) [C] 
     FROM [MyTable] 
    GROUP BY [Device]) q 

Ergebnisse: Der einzige Weg, ich meine, könnte, wie es mit einem UNION war zu tun

[CustomerName], [Rows], [A], [B], [C] 
'ALL CUSTOMERS', 6,  6, 4, 3 
'Customer A',  3,  3, 2, 2 
'Customer B',  2,  2, 1, 0 
'Customer C',  1,  1, 1, 1 
'UNIQUE DEVICES', 3,  3, 3, 2 

Das jetzt für meine Zwecke gut genug funktioniert, aber haben nicht viel Erfahrung mit ROLLUP hatte oder CUBE vorher dachte ich, ich würde versuchen zu sehen, ob ich das UNION loswerden und eine einzige SELECT haben könnte. Von der examples on MSDN unterstützt ROLLUP mehrere Gruppierungen, aber ich kann nicht herausfinden, wie man es erhält, um die Ergebnisse zu erzeugen, die ich will. Kann jemand demonstrieren, wie man eine einzelne SELECT verwendet, um diese Ergebnisse zu erhalten?

+0

Gruppieren nach, Rollup und Cube sind hierarchisch, aber Ihre gewünschte Ausgabe ist nicht. Was Sie getan haben, ist der einzige Weg, um das gewünschte Ergebnis zu bekommen :) –

+0

@ P.Salmon das ist, was ich hatte Angst, aber ich denke, dass es irgendwie möglich sein, wenn ich eine Doppel-Aggregation wie ich in der zweites 'SELECT'. –

+0

Es gibt Möglichkeiten, wie Sie dies in eine "single" -Abfrage bringen können (d. H. Nicht die 'UNION' verwenden), aber sie werden alle komplexeren/weniger verständlichen/weniger performanten Code beinhalten als das, was Sie bereits haben. Ich kann später ein Beispiel veröffentlichen, wenn Sie * wirklich * wollen, oder Sie können akzeptieren, dass @ P.Salmon es im Grunde auf den Kopf traf. – Jeff

Antwort

0

Ich brauche einen Bericht, der gleichzeitig drei Arten von Daten präsentiert:

Das bedeutet nicht unbedingt, müssen Sie eine Abfrage. Die gewünschten Ergebnisse sind logisch verschieden. Es gibt auch andere Möglichkeiten, um Bande alle sie zusammen, aber die einfachste Abfrage ist eine Vereinigung aller drei:

select CustomerName 
     , count(*) as Rows 
     , sum(cast(A as int)) as A 
     , sum(cast(B as int)) as B 
     , sum(cast(C as int)) as C 
from T 
group by CustomerName 
UNION 
select 'ALL CUSTOMERS' 
     , count(*) as Rows 
     , sum(cast(A as int)) as A 
     , sum(cast(B as int)) as B 
     , sum(cast(C as int)) as C 
from T 
UNION 
select 'UNIQUE DEVICES' 
     , count(*) as Rows 
     , sum(A) as A 
     , sum(B) as B 
     , sum(C) as C 
from (
     select Device 
       , max(cast(A as int)) as A 
       , max(cast(B as int)) as B 
       , max(cast(C as int)) as C 
     from T 
     group by Device 
) as A 

Die ganze Rollup/Würfel Sache war immer eine eigentümliche Katastrophe. Wenn Sie von seinen Einzelheiten profitieren, gut, verwenden Sie es, sonst empfehle ich, einen großen Bogen zu machen. Ich konnte deine Frage ohne deine Erklärung nicht ohne weiteres verstehen; im Gegensatz dazu, wage ich zu behaupten, dass die ersten beiden Teile von mir ohne Erklärung leicht verständlich sind.

Sie können Ansichten jeder der drei UNION Komponenten erstellen und sie auf andere, interessante Arten (neben der One Big Query) anordnen.

Kann jemand demonstrieren, wie man einen einzelnen SELECT benutzt, um diese Resultate zu erhalten?

Ihre Anfrage und meine sind sowohl einzelne SELECT Aussagen; UNION ist Teil von SELECT. Was ich denke du meinst ist, kann es ohne UNION gemacht werden, und diese Antwort ist Nein. Oder, vielleicht "ja, aber Sie werden es nicht mögen". Wie Sie selbst die Frage formuliert haben, möchten Sie die Daten in zwei verschiedene Möglichkeiten zusammenfassen. Diese zwei Möglichkeiten sind logisch eindeutig: nach Kunden und nach Flag.UNION ist der relationale Algebraoperator, der zwei Relationen verkettet, was genau das ist, wonach Sie gefragt haben! :-)

SQL Server unterstützt auch die OVER clause; Es ermöglicht komplexere Arten der Gruppierung, und Sie können es möglicherweise erhalten, um die gewünschten Ergebnisse ohne eine UNION zu produzieren. Aber ich bezweifle, dass das SQL so einfach zu verstehen und zu ändern ist, oder so wenig Zeilen wie das, was Sie bisher haben.

Verwandte Themen