2010-07-09 8 views
9

Ich habe eine Abfrage, an der ich arbeite, und ich möchte eines der Felder erhöhen und den Zähler neu starten, wenn ein Schlüsselwert anders ist.Wie in einer Select-Abfrage inkrementieren

Ich weiß, dass dieser Code nicht funktioniert. Programmatisch ist das, was ich will ...

declare @counter int, @id 
set @counter = 0 
set @id = 0 

select distinct 
    id, 
    counter = when id = @id 
       then @counter += 1 
      else @id = id 
       @counter = 1  

... mit dem Endergebnis etwas wie folgt aussehen:

ID Counter 
3  1 
3  2 
3  3 
3  4 
6  1 
6  2 
6  3 
7  1 

Und ja, ich bin mit SQL2K stecken. Ansonsten würde row_number() funktionieren.

+0

auf die Abhängigkeit Was ist in Ihrer Abfrage verfügbar? Vielleicht hilft die Row_Number()? – reallyJim

+0

@reallyJim: Wenn sie SQL2K verwenden, wie die Tags vorschlagen, dann ist 'ROW_NUMBER' nicht verfügbar. – LukeH

+0

@LukeH TOTALLY diesen Punkt verfehlt! – reallyJim

Antwort

12

eine Tabelle Angenommen:

CREATE TABLE [SomeTable] (
    [id] INTEGER, 
    [order] INTEGER, 
    PRIMARY KEY ([id], [order]) 
); 

Eine Möglichkeit, dies in Microsoft SQL Server zu erhalten 2000 eine Unterabfrage zu verwenden, um die Zeilen mit der gleichen ID zu zählen und eine niedrigere Reihenfolge.

SELECT *, (SELECT COUNT(*) FROM [SomeTable] counter 
      WHERE t.id = counter.id AND t.order < counter.order) AS row_num 
FROM [SomeTable] t 

Tipp: Es ist 2010. Bald SQL Server alt genug sein wird zu fahren. Wenn Sie SQL Server 2005 oder höher verwenden, erhalten Sie wunderbare neue Funktionen wie ROW_NUMBER() OVER (PARTITION...).

+5

SQL 2000 macht immer noch Spaß. Mit 13+ ist SQL Server 7.0 die meiste Zeit mürrisch und spielt Videospiele den ganzen Tag. –

+4

Wir arbeiten tatsächlich an SQL2ks erstem Auto. Wenn er seine Nase sauber hält und gute Noten bekommt, wird es sein Geburtstagsgeschenk sein. ; o) – Mikecancook

+3

Sie wachsen so schnell auf! * schnüffeln * –

6

Ja, Sie wollen ROW_NUMBER().

Ich würde versuchen:

SELECT id, ROW_NUMBER() OVER (PARTITION BY ID ORDER BY ID) AS Counter 
+0

Kann nicht - SQL Server unterstützt keine Analyse-/Rang-/Fensterfunktionen bis V2005 –

1

Mit row_number() müssen Sie mit weit, viel weniger korrelierten Unterabfragen umgehen. @ Bill Karwins Lösung funktioniert (+1); Hier ist eine andere Version, die das Gleiche tut, aber das könnte ein bisschen einfacher zu folgen sein. (I verwenden Datetimes Ordnung zu bestimmen.)

-- Test table 
CREATE TABLE Test 
(Id  int  not null 
    ,Loaded datetime not null 
) 

-- Load dummy data with made-up distinct datetimes 
INSERT Test values (3, 'Jan 1, 2010') 
INSERT Test values (3, 'Jan 2, 2010') 
INSERT Test values (3, 'Jan 5, 2010') 
INSERT Test values (3, 'Jan 7, 2010') 
INSERT Test values (6, 'Feb 1, 2010') 
INSERT Test values (6, 'Feb 11, 2010') 
INSERT Test values (7, 'Mar 31, 2010') 


-- The query 
SELECT t1.Id, count(*) Counter 
from Test t1 
    inner join Test t2 
    on t2.Id = t1.Id 
    and t2.Loaded <= t1.Loaded 
group by t1.Id, t1.Loaded 


-- Clean up when done 
DROP TABLE Test 

Es ist wichtig festzustellen, dass ohne guten Indizes (und vielleicht sogar mit ihnen), diese Arten von Abfragen können sehr schlecht durchführen, vor allem bei großen Tabellen. Überprüfen und optimieren Sie sorgfältig!

3

Eine Möglichkeit besteht darin, die Daten in eine temporäre Tabelle mit einer Identitätsspalte zu schreiben, die als Zeilennummer verwendet wird. Dann machen die Zählerspalte eine Zählung der anderen Reihen mit der gleichen Id und eine untere Reihe Nummer + 1.

CREATE TABLE #MyData(
Id INT 
); 

INSERT INTO #MyData VALUES(3); 
INSERT INTO #MyData VALUES(3); 
INSERT INTO #MyData VALUES(3); 
INSERT INTO #MyData VALUES(3); 
INSERT INTO #MyData VALUES(6); 
INSERT INTO #MyData VALUES(6); 
INSERT INTO #MyData VALUES(6); 
INSERT INTO #MyData VALUES(7); 

CREATE TABLE #MyTempTable(
RowNum INT IDENTITY(1,1), 
Id INT, 
Counter INT 
); 

INSERT INTO #MyTempTable 
SELECT Id, 0 
FROM #MyData 
ORDER BY Id; 

SELECT Id, (SELECT COUNT(*) + 1 FROM #MyTempTable WHERE Id = t1.Id AND RowNum < t1.RowNum) AS 'Counter' 
FROM #MyTempTable t1; 

Sie sollten die folgende Ausgabe auf dem Beispiel basiert erhalten:

Id Counter 
3 1 
3 2 
3 3 
3 4 
6 1 
6 2 
6 3 
7 1 
Verwandte Themen