我在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)。
我被告知创建光标是实现此目的的最佳方式,但我无法在网上找到任何看起来相似的内容。
这似乎应该是一件相对简单的事情。有人可以帮助我吗?
非常感谢!
答案 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为第二个,等等。)