2016-08-04 35 views
1

Ich habe eine Frage ganz ähnlich wie How to add sequence number for groups in a SQL query without temp tablesWie Sequenznummer für Gruppen (neue Nummer, wenn gleiche Gruppe wieder auftritt) in einer SQL-Abfrage

die Probe zu nehmen von dort zu schreiben, habe ich eine Datenstruktur, die aus die ersten beiden Spalte dieser Tabelle, und ich mag die dritte Spalte in meiner Anfrage generieren:

 
Record Group  GroupSequence 
-------|---------|-------------- 
1  Chickens 1 
2  Chickens 1 
3  Horses 2 
4  Cows  3 
5  Horses 4 
6  Horses 4 

der Unterschied zu der zitierten Abfrage ist, dass ich eine neue Nummer benötigen, wenn die vorherige Linie nicht über der gleiche Wert in der zweiten Spalte.

Ich habe versucht, eine Zeilennummer und LAG() zu verwenden, um zu überprüfen, ob die vorherige Zeile den gleichen Wert hatte - wenn ja, nehmen Sie den vorherigen Wert dieser generierten Spalte, wenn nicht, nehmen Sie die Zeilennummer - aber es sieht so aus Sie können die von Ihnen erstellte Spalte nicht erneut verwenden.

Der Wert muss nur eine andere Nummer sein - es spielt keine Rolle, ob es in Ordnung ist. Dies wäre auch in Ordnung sein:

 
Record Group  GroupSequence 
-------|---------|-------------- 
1  Chickens 1 
2  Chickens 1 
3  Horses 3 
4  Cows  4 
5  Horses 5 
6  Horses 5 
+0

warum nicht 2 für Pferde in zweiter Ausgabe? – TheGameiswar

+0

@TheGameiswar Wenn ich 2 oder 3 für 'Pferde' bekomme, ist es mir egal. Es muss nur eine andere Nummer sein, wenn die vorherige Zeile nicht den gleichen Wert hat. Es kommt darauf an, dass die zweite Gruppe von Pferden eine andere Nummer hat als die erste Gruppe. – SimonSimCity

+1

Lesen Sie etwas auf RANK() und DENSE_RANK() Funktionen – PacoDePaco

Antwort

2

Ich denke, das ist das, was Sie brauchen:

WITH Src AS 
(
    SELECT * FROM (VALUES 
    (1, 'Chickens'), 
    (2, 'Chickens'), 
    (3, 'Horses '), 
    (4, 'Cows '), 
    (5, 'Horses '), 
    (6, 'Horses '))T(Record, [Group]) 
), Differentiator AS 
(
    SELECT *, 
    ROW_NUMBER() OVER (ORDER BY Record) - 
     RANK() OVER (PARTITION BY [Group] ORDER BY Record) Diff 
    FROM Src 
) 
SELECT Record, [Group], DENSE_RANK() OVER (ORDER BY [Group],Diff) NewGroup 
FROM Differentiator 
ORDER BY Record 

Es produziert folgende Tabelle:

Record Group  NewGroup 
------ -----  -------- 
1  Chickens 1 
2  Chickens 1 
3  Horses  3 
4  Cows  2 
5  Horses  4 
6  Horses  4 

Kurze Erklärung:

Die Der Schlüssel besteht darin, die relativen Positionen der Datensätze in der gesamten Tabelle und in jedem zu berechnen Gruppe [Gruppe]. Wenn Datensätze benachbart sind, wird die globale Nummer um 1 erhöht und die lokale Nummer wird um 1 erhöht. Somit ist ROW_NUMBER() - RANK() für alle Datensätze identisch. Wenn es eine Lücke gibt, gibt es auch eine Verzerrung der globalen Nummerierung. Es führt zu unterschiedlichen Nummern, die von ROW_NUMBER() - RANK() in getrennten Gruppen erzeugt werden.

+0

es hat mich nur umgehauen. All dies trickst mit Zahlen, mit denen du es hier zu tun hast ... Kannst du mir bitte erklären, wie es funktioniert? Um nur den Kopf herumzulegen und zu beweisen, dass es in der Spalte "NewGroup" nie eine falsche Nummer geben wird? – SimonSimCity

+0

Verstanden. Das ist ziemlich schlau. Ich dachte zuerst, dass es irgendwann wieder einen Konflikt geben würde, aber wenn Diff größer wird, wenn Record steigt, wird es niemals eine Gruppen-Diskrepanz geben (als hätte man eine Nummer für zwei verschiedene Gruppen im Ergebnis). – SimonSimCity

+1

Ich habe eine kurze Erklärung und 'ROW_NUMBER' hinzugefügt, um Lücken in der' Record'-Spalte zu behandeln. –