手动指定 Row_Number() 的起始值

Posted

技术标签:

【中文标题】手动指定 Row_Number() 的起始值【英文标题】:Manually specify starting value for Row_Number() 【发布时间】:2013-02-19 01:02:40 【问题描述】:

我想将ROW_NUMBER() 的开头定义为3258170 而不是1

我正在使用以下 SQL 查询

SELECT ROW_NUMBER() over(order by (select 3258170))  as 'idd'.

但是,上述查询不起作用。当我说不工作时,我的意思是它正在执行,但它不是从3258170 开始的。有人可以帮帮我吗?

我想指定行号的原因是我将行从一个表插入到另一个表。在第一个表中,最后一条记录的行号是 3258169,当我插入新记录时,我希望它们具有来自 3258170 的行号。

【问题讨论】:

0_0 我不确定这样的事情是否可行,但我确定这是一个可怕的想法。你实际上想要完成什么? SQL Server 具有自动递增的整数列,不是吗? 不能添加一个自增主键来保持正确的ID吗? 是的,我能做到。只是想看看有没有其他方法。 【参考方案1】:

只需将值添加到row_number() 的结果中即可:

select 3258170 - 1 + row_number() over (order by (select NULL)) as idd

row_number()order by 子句指定用于排序依据的列。通过在此处指定一个常量,您只是在说“出于排序目的,所有内容都具有相同的值”。它与选择的第一个值没有任何关系。

为避免混淆,我将常量值替换为 NULL。在 SQL Server 中,我观察到这会分配一个序列号而不实际对行进行排序 - 观察到的性能优势,但不是我见过的记录,所以我们不能依赖它.

【讨论】:

@John - 您需要了解 ROW_NUMBER() 是什么,并且您不能为其赋值。你只能添加它。来自 Oracle 文档:“ROW_NUMBER 是一个分析函数。它在 order_by_clause 中指定的行的有序序列中为应用它的每一行(分区中的每一行或查询返回的每一行)分配一个唯一编号,从 1 开始。” 对于 mysql,请参阅 OMG Ponies 答案:***.com/questions/1895110/row-number-in-mysql【参考方案2】:

我觉得这更容易

ROW_NUMBER() OVER(ORDER BY Field) - 1 AS FieldAlias (To start from 0)
ROW_NUMBER() OVER(ORDER BY Field) + 3258169 AS FieldAlias (To start from 3258170)

【讨论】:

【参考方案3】:

有时……

ROW_NUMBER() 可能不是最佳解决方案,尤其是当基础数据集中可能存在重复记录时(对于 JOIN 查询等)。这可能会导致返回的行数超出预期。您可以考虑创建一个 SEQUENCE,这在某些情况下可能被认为是更清洁的解决方案。 即:

CREATE SEQUENCE myRowNumberId  
    START WITH 1  
    INCREMENT BY 1 
GO  

SELECT NEXT VALUE FOR myRowNumberId  AS 'idd' -- your query
GO

DROP SEQUENCE myRowNumberId; -- just to clean-up after ourselves
GO

缺点是序列可能难以在具有 DISTINCT、WINDOW 函数等的复杂查询中使用。请参阅完整的序列文档 here。

【讨论】:

【参考方案4】:

我有一种情况,我将分层结构导入应用程序,其中 seq 编号在每个分层级别中必须是唯一的,并且从 110 开始(以便于后续手动插入)。之前的数据是这样的……

Level Prod        Type  Component      Quantity     Seq
1   P00210005       R   NZ1500         57.90000000  120
1   P00210005       C   P00210005M     1.00000000   120
2   P00210005M      R   M/C Operation   20.00000000 110
2   P00210005M      C   P00210006      1.00000000   110
2   P00210005M      C   P00210007      1.00000000   110

我希望 row_number() 函数生成新的序列号,但无法按预期实现加 10 然后乘以 10。要强制执行算术函数序列,您必须将整个 row_number() 和 partition 子句括在括号中。您只能对 row_number() 进行简单的加减运算。

所以,我对这个问题的解决方案是

,10*(10+row_number() over (Partition by Level order by Type desc, [Seq] asc)) [NewSeq]

注意括号的位置,以便在加法之后进行乘法。

Level Prod        Type  Component      Quantity     [Seq] [NewSeq]
1   P00210005       R   NZ1500        57.90000000   120   110
1   P00210005       C   P00210005M    1.00000000    120   120
2   P00210005M      R   M/C Operation 20.00000000   110   110
2   P00210005M      C   P00210006     1.00000000    110   120
2   P00210005M      C   P00210007     1.00000000    110   130

【讨论】:

以上是关于手动指定 Row_Number() 的起始值的主要内容,如果未能解决你的问题,请参考以下文章

分组 根据某一列进行排序,根据shopid分组,用createTime排序,返回row_number()序号 select no =row_number() over (partition by s

jqgrid使用sql row_number进行分页

交叉应用中的 ROW_NUMBER 基于存在子句生成“不正确”值

Oracle 分析函数 ROW_NUMBER() 使用

Informix 的 Row_number() 函数

ROW_NUMBER() OVER(PARTITION BY COLUMN ORDER BY COLUMN DESC)函数的使用