Как увеличить в запросе Select

У меня есть запрос, я продолжаю работать, и я хочу увеличить одно из полей и перезапустить счетчик, когда значение ключа отличается.

Я знаю, что этот код не работает. Программно это - то, что я хочу...

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     

... с выглядящим примерно так конечным результатом:

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

И да, я застреваю с SQL2k. Иначе это row_number () работало бы.

10
задан OMG Ponies 9 July 2010 в 17:58
поделиться

4 ответа

Предполагая таблицу:

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

Один из способов получить это в Microsoft SQL Server 2000 - использовать подзапрос для подсчета строк с одинаковым id и более низким порядком.

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

Совет: На дворе 2010 год. Скоро ваш SQL Server будет достаточно стар, чтобы водить машину.

Если вы используете SQL Server 2005 или более позднюю версию, вы получите новые замечательные функции, такие как ROW_NUMBER() OVER (PARTITION...)

13
ответ дан 3 December 2019 в 16:51
поделиться

Да, вам нужен ROW_NUMBER().

Я бы попробовал:

SELECT id, ROW_NUMBER() OVER (PARTITION BY ID ORDER BY ID) AS Counter
8
ответ дан 3 December 2019 в 16:51
поделиться

Наличие row_number () означает, что вам придется иметь дело с гораздо меньшим количеством коррелированных подзапросов. Решение @Bill Karwin работает (+1); вот еще одна версия, которая делает то же самое, но которой будет немного легче следовать. (Я использовал дату и время для определения порядка.)

--  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

Важно отметить, что без хороших индексов (и, возможно, даже с ними) такие запросы могут работать очень плохо, особенно с большими таблицами. Внимательно проверяйте и оптимизируйте!

0
ответ дан 3 December 2019 в 16:51
поделиться

Один из способов сделать это - бросить данные в временную таблицу с идентификационным столбцом, который используется в качестве номера строки. Затем сделать столбец counter подсчетом других строк с тем же Id и меньшим номером строки + 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;

Вы должны получить следующий результат, основанный на вашем примере:

Id  Counter
3   1
3   2
3   3
3   4
6   1
6   2
6   3
7   1
3
ответ дан 3 December 2019 в 16:51
поделиться
Другие вопросы по тегам:

Похожие вопросы: