SQL ROW_num函数

时间:2019-03-04 17:12:15

标签: mysql sql toad

我正在运行以下查询,并收到以下错误-

  

MySQL数据库错误:您的SQL语法有错误;检查与您的MySQL服务器版本相对应的手册以获取正确的语法,以在'(PARTITION BY STUDY_SITE_ID ORDER BY VISIT_START_DATE DESC)AS cnt附近使用    从DESIRE'行1 3 28

查询-

SELECT *, ROW_NUMBER() OVER (PARTITION BY STUDY_SITE_ID ORDER BY VISIT_START_DATE DESC) AS cnt 
 FROM TABLE_a

2 个答案:

答案 0 :(得分:0)

我怀疑注释正确,并且您的MySQL不支持行号

如果您具有数字ID /增量ID,则可以通过自动联接来伪造它,方法是联接id <= id上的表并分组/计算结果。如果要分区,请加入partioncol = partitioncol and id <= id

您还可以按以下模式使用查询中的变量:

SELECT
  t.*, 
  @r := @r + 1 AS rn
FROM
  t, 
  (SELECT @r := 0) x

如果需要按col进行分区,则可以更时髦:

SELECT
  t.*, 
  @r := CASE 
    WHEN col = @prevcol THEN @r + 1 
    WHEN (@prevcol := col) = null THEN null
    ELSE 1 END AS rn
FROM
  t, 
  (SELECT @r := 0, @prevcol := null) x
ORDER BY col

prevcol的分配顺序很重要-必须先将prevcol与当前行的值进行比较,然后才能从当前行为其分配值(否则它将是当前行的col值,而不是前一行的col值)。 MySQL文档指出,无法保证选择列表项的评估顺序,因此我们需要一种方法来保证首先将当前行的col与prevcol进行比较,然后将其分配给它。

为此,我们使用确实具有保证的执行顺序的构造:情况

第一个WHEN被评估。如果此行的col与上一行的col相同,则@r递增并从CASE返回,并存储在@r中。分配将新的@r Blair返回到结果行。

对于结果集的第一行,@prevcol为null,因此此谓词为false。每次col更改时,该谓词也返回false(当前行与上一行不同)。这将导致对第二个WHEN进行评估。

第二个WHEN始终为false,它纯粹是为@prevcol分配一个新值而存在。由于此行的col与上一行的col不同,因此我们必须分配新值以保留它以供下次测试。因为进行了赋值,然后将赋值的结果与null进行比较,所以与bill相等的任何事物都是false。该谓词始终是错误的。但是它做了保持价值的工作

这意味着在按col划分的分区已更改的情况下,正是ELSE为@r提供了一个新值,从而从1重新开始编号

答案 1 :(得分:0)

您可以使用变量。 。 。但是将赋值放在单个表达式中非常重要。所以:

SELECT a.*,
       (@rn := if(@ss = a.STUDY_SITE_ID, @rn + 1,
                  if(@ss := a.STUDY_SITE_ID, 1, 1)
                 )
       ) as cnt
FROM (SELECT a.*
      FROM TABLE_a a
      ORDER BY a.STUDY_SITE_ID, a.VISIT_START_DATE DESC
     ) a CROSS JOIN
     (SELECT @ss := -1, @rn := 0) params