2016-06-18 3 views
2

Zum Beispiel, sollten Sie die folgenden Daten:Wie teilt man Datensätze in Gruppen auf, die durch die Gesamtsumme einer bestimmten Spalte definiert sind?

DECLARE @data TABLE (Id INT, Value INT) 
INSERT INTO @data VALUES 
(0,1), 
(1,2), 
(2,3), 
(3,1), 
(4,1), 
(5,1) 

Ich möchte diese Daten in das folgende zu transformieren:

Id Value Group 
0 1  0 
1 2  0 
2 3  1 
3 1  2 
4 1  2 
5 1  2 

Wenn die Elemente in der Reihenfolge ihrer Ids Inspektion berechnen wir die Gesamt laufende Summe von Value. Wenn es 3 erreicht, sagen wir, dass die Gruppe abgeschlossen ist und eine neue Gruppe und eine neue Gesamtsumme beginnt. Auf diese Weise ergeben die gegebenen Daten 3 Gruppen (wenn natürlich in der spezifischen Reihenfolge geprüft).

Kann ich die Group in Sql Server 2012 berechnen?

Bitte beachten Sie, dass dieses Beispiel etwas erfunden ist. Die reellen Zahlen sind größer und es gibt viele von ihnen. Die Summenschwelle kann auch ein BIGINT sein.

+0

@RyanVincent: Ist sehr einfach, diese Gruppen zu berechnen. Siehe meine Lösung. –

+0

Ich sag nur ... Ich wünschte, jeder hätte die @table gepostet, wie du es getan hast. –

Antwort

1
;WITH cte AS (
SELECT Id, 
     [Value], 
     [Value] as sum_val, 
     0 as grp 
FROM @data 
WHERE Id = 0 
UNION ALL 
SELECT d.id, 
     d.[Value], 
     CASE WHEN LAG(sum_val,0,0) OVER (ORDER BY c.Id) = 3 OR d.[Value] = 3 THEN d.[Value] ELSE sum_val+c.[Value] END, 
     CASE WHEN LAG(sum_val,0,0) OVER (ORDER BY c.Id) = 3 OR d.[Value] = 3 THEN grp+1 ELSE grp END 
FROM @data d 
INNER JOIN cte c 
    ON d.Id = c.Id+1 
) 

SELECT id, 
     [Value], 
     grp 
FROM cte 

Gibst du:

id Value grp 
0 1  0 
1 2  0 
2 3  1 
3 1  2 
4 1  2 
5 1  2 

hinzufügen Wenn

(6,2), 
(7,0), 
(8,1), 
(9,3) 

Um @data Tabelle, wird ausgegeben:

id Value grp 
0 1  0 
1 2  0 
2 3  1 
3 1  2 
4 1  2 
5 1  2 
6 2  3 
7 0  3 
8 1  3 
9 3  4 

Ich denke, das Problem wird, wenn Sie auftritt passiere fe (0,2),(1,2), wie man Gruppe in dieser Situation zählt?

2

Wenn der erste Wert min. 1 und alle Quellwerte sind INT/(Sehr klein, Klein, INT oder BIG), dann würde ich folgende verwenden Abfrage

SELECT * 
FROM (
SELECT *, (SUM(v.Value) OVER(ORDER BY v.Id) - 1)/3 AS Grp 
    FROM @data v 
) a 

Demo

+2

Elegant. Ich habe mit Modulo gespielt –