2010-07-09 17 views
9

Tengo una consulta en la que estoy trabajando y quiero incrementar uno de los campos y reiniciar el contador cuando el valor de una clave es diferente.Cómo incrementar en una consulta de selección

Sé que este código no funciona. Programación esto es lo que quiero ...

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  

... con el resultado final buscando algo como esto:

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

Y sí, estoy atascado con SQL2K. De lo contrario, row_number() funcionaría.

+0

Dependiendo de la el resto de lo que está disponible en su consulta, quizás el Row_Number() ayudaría? – reallyJim

+0

@reallyJim: si están usando SQL2K, como sugieren las etiquetas, entonces 'ROW_NUMBER' no estará disponible. – LukeH

+0

@LukeH TOTALMENTE se perdió ese punto! – reallyJim

Respuesta

12

Suponiendo una tabla:

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

Una forma de conseguir esto en Microsoft SQL Server 2000 es utilizar una subconsulta para contar las filas con el mismo ID y un orden inferior

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

Consejo: Es 2010. Pronto su SQL Server será suficiente edad para conducir.

Si utiliza SQL Server 2005 o posterior, obtendrá maravillosas funciones nuevas como ROW_NUMBER() OVER (PARTITION...).

+5

SQL 2000 sigue siendo divertido. A los 13 años o más, SQL Server 7.0 está malhumorado la mayor parte del tiempo y juega videojuegos todo el día. –

+4

Estamos trabajando en el primer auto de SQL2k. Si mantiene la nariz limpia y saca buenas notas, será su 16 regalo de cumpleaños. ; o) – Mikecancook

+3

¡Crecen tan rápido! * sniff * –

6

Sí, quieres ROW_NUMBER().

me gustaría probar:

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

No se puede: SQL Server no admite funciones de análisis/rango/ventanas hasta v2005 –

1

Tener row_number() significa que tiene que ocuparse de mucho, mucho menos subconsultas correlacionadas. La solución de @Bill Karwin funciona (+1); Aquí hay otra versión que hace lo mismo pero que podría ser un poco más fácil de seguir. (Utilicé datetimes para determinar el pedido.)

-- 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 importante señalar que, sin buenos índices (y tal vez incluso con ellos), este tipo de consultas se pueden realizar muy mal, sobre todo en tablas grandes. ¡Controla y optimiza con cuidado!

3

Una forma de hacer esto es arrojar los datos en una tabla temporal con una columna de identidad que se utiliza como número de fila. A continuación, realice la columna del mostrador un recuento de las otras filas con el mismo ID y un número de fila más baja + 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; 

Usted debe obtener la siguiente salida en función de su ejemplo:

Id Counter 
3 1 
3 2 
3 3 
3 4 
6 1 
6 2 
6 3 
7 1 
Cuestiones relacionadas