如何在选择查询中增加

时间:2010-07-09 16:17:37

标签: sql sql-server tsql sql-server-2000

我有一个正在处理的查询,我想增加其中一个字段,并在键值不同时重新启动计数器。

我知道这段代码不起作用。以编程方式这就是我想要的......

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()将起作用。

5 个答案:

答案 0 :(得分:13)

假设一张桌子:

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

答案 1 :(得分:6)

是的,你想要ROW_NUMBER()。

我会尝试:

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

答案 2 :(得分:3)

执行此操作的一种方法是将数据放入临时表中,该临时表具有用作行号的标识列。然后使计数器列成为具有相同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 :(得分:0)

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

重要的是要注意,如果没有好的索引(甚至可能使用它们),这些类型的查询可能表现得非常糟糕,特别是在大型表上。仔细检查和优化!

答案 4 :(得分:0)

对于MySql,我可以通过此查询来实现。

SELECT (SELECT COUNT(id) +1 FROM sku s WHERE t.item_id = s.item AND s.id < t.sku_id) AS rowNumber, t.*
FROM
(select item.Name as itemName ,item.id as item_id , sku.Name as skuName ,sku.id as sku_id from item
    INNER JOIN sku ON item.id = sku.item
    WHERE item.active = 'Y' 
) t


1   Roasted Pistachios (Salted, In Shell)   84  1 Pound Bags    84
3   Roasted Pistachios (Salted, In Shell)   84  25 Pound Cases  1174
5   Roasted Pistachios (Salted, In Shell)   84  12 x 2.6 Ounce Bags 5807
2   Roasted Pistachios (Salted, In Shell)   84  5 Pound Bags    814
4   Roasted Pistachios (Salted, In Shell)   84  Samples 4724
6   Roasted Pistachios (Salted, In Shell)   84  12 x 3.2 Ounce Bags 18145
4   Star Fruit  981 5 Pound Bags    17462
1   Star Fruit  981 1 Pound Bags    2125
3   Star Fruit  981 11 Pound Bags   2226
2   Star Fruit  981 44 Pound Cases  2156