ROW_NUMBER() OVER 函数没有遍历所有记录

Posted

技术标签:

【中文标题】ROW_NUMBER() OVER 函数没有遍历所有记录【英文标题】:ROW_NUMBER() OVER Function did not run through all records 【发布时间】:2018-02-14 15:37:38 【问题描述】:

我有一张这样的桌子

ID  Date    Sale    Sale_desc
1   1/1/2017    10  book
1   1/1/2017    10  book
1   1/1/2017    10  book
2   1/2/2017    12  notebook
2   1/2/2017    12  notebook
3   1/3/2017    1   pen
3   1/3/2017    1   pen

我运行以下查询来获取行号:

select *, row_number() over (partition by id order by date) 
from the_table;

但结果不是我所期望的。

ID  Date        Sale    Sale_desc   row_num
1   1/1/2017    10      book        1
1   1/1/2017    10      book        1
1   1/1/2017    10      book        1
2   1/2/2017    12      notebook    1
2   1/2/2017    12      notebook    2
3   1/3/2017    1       pen         1
3   1/3/2017    1       pen         2

前 3 行的 row_num 应该是 1、2、3,但看起来 row_num() 并没有遍历所有行。请帮忙。谢谢

【问题讨论】:

尽量把理解你的问题所需的一切都放在问题的文本中。 这看起来很奇怪,对于其他 ID 来说是正确的。您可以将其重写为COUNT(*) over (partition by id order by date ROWS UNBOUNDED PRECEDING),检查是否返回正确的结果。 到底是哪个数据库?它可以在 11g XE 上正常工作(即,正如您所希望的那样)。 【参考方案1】:

当我运行相同的代码时,我会得到您期望的结果。我对可能与您使用的列类型不同的列类型做了一些假设。我正在使用默认排序规则进行测试,这可能会影响字符串比较。

如果您运行相同的测试用例并获得正确的结果,那么问题出在代码的其他地方。我们需要查看更多原始查询和架构才能找到问题。

declare @Test table
(
    ID int,
    [Date] Date,
    Sale int,
    Sale_desc varchar(50)
)

insert into @Test
(ID, [Date], Sale, Sale_desc)
select 1, '1/1/2017', 10, 'book'     union all
select 1, '1/1/2017', 10, 'book'     union all
select 1, '1/1/2017', 10, 'book'     union all
select 2, '1/2/2017', 12, 'notebook' union all
select 2, '1/2/2017', 12, 'notebook' union all
select 3, '1/3/2017', 1 , 'pen'      union all
select 3, '1/3/2017', 1 , 'pen'

select
    *,
    row_number() over (partition by id order by [date]) as row_num
from @test

结果:

ID  Date        Sale  Sale_desc   row_num
1   2017-01-01  10    book        1
1   2017-01-01  10    book        2
1   2017-01-01  10    book        3
2   2017-01-02  12    notebook    1
2   2017-01-02  12    notebook    2
3   2017-01-03  1     pen         1
3   2017-01-03  1     pen         2

【讨论】:

【参考方案2】:

我猜你的 id 列是字符串 (VARCHAR/CHAR)。你可以试试:

select *, row_number() over (partition by CAST(id AS INTEGER) order by date) 
from the_table;

Rextester demo

【讨论】:

如果是关于数据类型,它不适用于其余数据。无论如何,谢谢你的回答 @DanTr 这是基于有限信息的疯狂猜测。您的代码应该“按原样”工作。我描述了所见即所得的场景。

以上是关于ROW_NUMBER() OVER 函数没有遍历所有记录的主要内容,如果未能解决你的问题,请参考以下文章

ROW_NUMBER() OVER()函数用法;(分组,排序),partition by

MySQL - 排序函数 Rank() Over()Dense_rank() Over()Row_number() Over()

Oracle 分析函数 ROW_NUMBER() 使用

Oracle中ROW_NUMBER() OVER()函数用法

关于Oracle row_number() over()的简单使用

ROW_NUMBER() OVER()函数用法详解