为什么row_number不能对相同的记录使用 Null 值?

Why row_number is not working with Null value for same records?

提问人:Amit Desai 提问时间:4/2/2023 最后编辑:marc_sAmit Desai 更新时间:4/3/2023 访问量:561

问:

我正在尝试为同一 ID 存在多行的查询之一应用行号。

例如,这是我的表格

现在,当我使用这段代码时:row_number over partition

ROW_NUMBER() OVER (PARTITION BY ID, Race, ethnicity, Awards 
                   ORDER BY EnthnictyID ASC)

我得到这个:

This is what I am getting after applying ROW_NUM

有数以百万计的记录存在同样的问题。

简而言之,我想用 value 替换 Null,并且确认所有 ID 都有自己的种族、民族和奖项,因此所有 ID 都应该在各自的列中具有值。

任何帮助将不胜感激!

谢谢

但我想看到这个:ROW_NUMBER

Final Result with Value in Ethnicity

我已经应用了解决方案。

  1. 使用 ,但它确实对某些人有效,对其他人无效。MINMAXGROUP BY
  2. 通过仅调用它,它返回带有值的重复项和一个带有值的重复项。ROW_NUMBER = 1NULL
sql-server t-sql null 分区 行号

评论

2赞 markalex 4/2/2023
请不要上传代码/数据/错误的图像。
1赞 Charlieface 4/3/2023
也许你只是想要所需的确切逻辑尚不清楚。ROW_NUMBER() OVER (PARTITION BY ID ORDER BY Race DESC, ethnicity DESC, Awards DESC)
1赞 siggemannen 4/3/2023
我认为他想从为相同 ID 设置的另一行预先填充种族,然后row_number做这件事
2赞 siggemannen 4/3/2023
我认为你在 excel 中想得太多了。下一行是什么?sql中没有这样的东西,除非你指定如何,否则行不会自动排序。此外,如果下一行也具有 NULL,会发生什么情况。如果在不同的列中有多个 NULL,会发生什么情况。

答:

1赞 MarcinJ 4/2/2023 #1

你会得到两个不同的行号,因为 NULL 不等于 'White'。事实上,NULL 不等同于其他任何东西,甚至不等于 NULL,这就是存在构造的原因。因此,由于引擎将 White 和 NULL 视为两个不同的值,因此在窗口函数中将获得两个不同的分区。IS [NOT] NULL

如果只是想在列为 NULL 时使用某种统一的默认值,则可以将该列包装在 中,例如:ISNULL(..., <default_value>)

ROW_NUMBER() OVER(PARTITION BY ID, Race, ISNULL(Ethnicity, 'White'), Awards ORDER BY EnthnictyID ASC)

这将使任何为 NULL 的种族等于“白人”。或者,如果缺少种族,您可能希望将其等同于种族:

ROW_NUMBER() OVER(PARTITION BY ID, Race, ISNULL(Ethnicity, Race), Awards ORDER BY EnthnictyID ASC)

这更具动态性,因为如果您有一行的 Race = Black, Ethnicity = NULL,它会将该行划分为与 Race = Black, Ethnicity = Black 相同的部分,而不是 Race = Black, Ethnicity = White,您将在 中获得默认常量。ISNULL(Ethnicity, 'White')

现在,如果您尝试识别每个 ID 的重复项,并找出哪些行填充了最多的列,然后删除其余的列,您可能希望按 ID 分区,然后按您拥有的非 null 列的数量排序,这将略有不同:

SELECT *
     , ROW_NUMBER() OVER (PARTITION BY ID 
                          ORDER BY IIF(Race IS NOT NULL, 1, 0) 
                                 + IIF(Ethnicity IS NOT NULL, 1, 0)   
                                 + IIF(Awards IS NOT NULL, 1, 0)
                              DESC) AS rn

  FROM yourTable

正如我在这里所做的那样,您可以在 or 子句中使用各种表达式,这里我基本上按非 null 字段的计数排序(每个非 null 值生成 1,null 值生成 0)。PARTITION BYORDER BY

评论

0赞 Amit Desai 4/3/2023
非常感谢您的回复。我按照你说的顺序尝试过,但抛出了相同的结果。我到底想要的是;我想将 null 值替换为同一列中的值,而不是来自 RACE。例如,在屏幕截图中,您可以看到下一个值(第二行)在“种族”下是“白色”,因此我想分组依据并将 NULL 值替换为 WHITE。这就是它如何给出包含列中所有值的单行。希望你明白了!谢谢