使用游标在SQL中创建计数器

时间:2013-07-24 13:59:26

标签: sql

我在SQL中创建重复的计数器变量时遇到了麻烦。这是我想要做的 -

x_id       date                 num       p_id       Counter
2113       4/1/2013              11           444         1
2113       4/1/2013              11           445         2
2113       4/1/2013              21           448         3
2113       4/1/2013              21           460         4
2113       4/1/2013              21           461         5
2113       4/1/2013              31           463         6
2116       4/1/2013              7              982         1
2116       4/1/2013              7              985         2
2116       4/1/2013              8              987         3

当我通过x_id,date,num和p_id订购这些数据时,我拥有了创建计数器列所需的一切。

我遇到的困难是在我想要的地方打破并重新启动此计数器列。我希望计数器在每次发生新的x_id /日期配对时重新开始(所以如果有任何更改,计数器应该返回到1)。

我被告知创建光标是实现此目的的最佳方式,但我无法在网上找到任何看起来相似的内容。

这似乎应该是一件相对简单的事情。有人可以帮助我吗?

非常感谢!

3 个答案:

答案 0 :(得分:3)

如果您正在使用支持窗口功能的数据库系统,那么这是ROW_NUMBER的工作:

select x_id,date,num,p_id,
  ROW_NUMBER() OVER (PARTITION BY x_id, date ORDER BY num, p_id) as counter
from table

SQL Server help for ROW_NUMBER(),但它也得到许多其他数据库系统的支持,例如Oracle,PostgreSQL,DB2(但不是MySQL):

  

返回结果集分区中行的序号,从1开始,每个分区的第一行

答案 1 :(得分:1)

MySQL解决方案:

您不需要光标用于此

SELECT
yt.*,
@counter := CASE WHEN @prev_x != x_id OR @prev_date != `date` THEN 1 ELSE @counter + 1 END AS counter,
@prev_x := x_id,
@prev_date := `date`
FROM yourTable yt
, (SELECT @counter:=1, @prev_x:=NULL, @prev_date:=NULL) vars
ORDER BY x_id, `date`, num, p_id

答案 2 :(得分:0)

假设您正在使用SQL Server / TSQL:

不要使用游标,而是使用DENSE_RANK()功能。

SELECT x_id, date, num, p_id, DENSE_RANK() OVER (ORDER BY x_id, date) as Counter FROM Table

UPDATE :再次重新阅读这个问题,这可能不是上述情况的正确解决方案,它将保持相同的相同值,直到相关值发生变化(前六行为1, 2为第二个,等等。)