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

使用游标在SQL中创建计数器,sql,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

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

有人告诉我,创建一个光标是最好的方法,但我在网上找不到任何类似的例子

看起来这应该是一件相对简单的事情。有人能帮我吗

非常感谢

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

如果您使用的数据库系统支持窗口功能,则这是
行编号
s作业:

select x_id,date,num,p_id,
  ROW_NUMBER() OVER (PARTITION BY x_id, date ORDER BY num, p_id) as counter
from table
,但许多其他数据库系统也支持它,如Oracle、PostgreSQL、DB2(但不支持MySQL):

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


假设您使用的是SQL Server/TSQL:

不要使用游标,而是使用函数

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

更新:再次阅读问题,对于上述场景,这可能不是正确的解决方案,它将保持计数器不变,直到相关值发生变化(前六行为1,后三行为2,等等)

因此,在上述场景中,前6行的计数器应为1,后3行的计数器应为2?哪个数据库系统和所述数据库系统的哪个版本?感谢所有回复。如果有帮助的话,我正在Mac上使用MAMP和Sequel Pro。Id是什么样的(一旦数据按上面的顺序排列),对于x_Id/日期配对,计数器将增加1,然后在新配对发生时重新开始-因此计数器的外观应与上面的一样。
densite_RANK
在需要计数器时是错误的函数。它可能会将相同的值分配给多行。我认为这是OP的原始想法(在评论中询问,但尚未收到回复)“出现新的x_id/日期配对…计数器应返回到1”应该更仔细,谢谢。将评论我的解决方案+1(因为是正确的)。而且,
row_number()
是ANSI标准,大多数主要数据库都支持它。至少:SQL Server、Oracle、DB2、Teradata和Postgres及其许多衍生产品。@GordonLinoff-在我的答案中添加了一个部分列表,并突出显示了我认为不支持它的部分列表(一如既往,如果OP包含数据库系统信息会容易得多)。这将是完美的,但我使用的是MySQL。还有其他建议吗?@SoxBoston-看起来像fancyPants提供的,但我不能评论它的正确性(目前看来它只打开
x_id
值,可能是因为
date
在样本数据中没有变化,但可能可以修改),尽管
date
在样本数据中没有变化,叙述似乎说,日期的更改也应该重置计数器。这是正确的。我应该把它说得更清楚,但是日期确实会改变,并且会重新设置计数器。