Sim*_*onN 4 sql-server null row-number
我发现这种行为非常奇怪且违反直觉。(即使对于 SQL)。
set ansi_nulls off
go
;with sampledata(Value, CanBeNull) as
(
  select 1, 1
  union 
  select 2, 2
  union 
  select 3, null
  union 
  select 4, null
  union 
  select 5, null
  union 
  select 6, null
)
select ROW_NUMBER() over(partition by CanBeNull order by      value) 'RowNumber',* from sampledata
哪个返回
1   3   NULL
2   4   NULL
3   5   NULL
4   6   NULL
1   1   1
1   2   2
这意味着为了计算行号,所有空值都被视为同一组的一部分。SET ANSI_NULLLS 是打开还是关闭都没有关系。但是,根据定义,null 是完全未知的,那么如何将 null 像这样组合在一起呢?据说为了将事物按等级顺序排列,苹果和橙子以及负 1 的平方根和量子黑洞或任何可以有意义地排序的东西。一些实验表明,第一列用于生成排名顺序为
  select 1, '1'
  union 
  select 2, '2'
  union 
  select 5, null
  union 
  select 6, null
  union
  select 3, null
  union 
  select 4, null
生成相同的值。这具有重大影响,导致我正在处理的遗留代码出现问题。这是预期的行为吗,除了用唯一值替换 select 查询中的 null 之外,还有什么方法可以减轻它吗?
我所期望的结果是
1   3   NULL
1   4   NULL
1   5   NULL
1   6   NULL
1   1   1
1   2   2
使用 Dense_Rank() 没有区别。
小智 6
哟。
所以问题是,当 T-SQL 处理谓词中的 NULL 时,它使用三元逻辑(TRUE、FALSE 或 UNKNOWN)并显示您声明的您期望从查询中得到的行为。但是,在对值进行分组时,T-SQL 将 NULL 视为一组。因此,您的查询会将 NULL 分组在一起并开始对该窗口中的行进行编号。
对于您说希望看到的结果,此查询应该有效...
WITH sampledata (Value, CanBeNull)
AS
(
    SELECT 1, 1
    UNION
    SELECT 2, 2
    UNION
    SELECT 3, NULL
    UNION
    SELECT 4, NULL
    UNION
    SELECT 5, NULL
    UNION
    SELECT 6, NULL
)
SELECT
    DENSE_RANK() OVER (PARTITION BY CanBeNull ORDER BY CASE WHEN CanBeNull IS NOT NULL THEN value END ASC) as RowNumber
    ,Value
    ,CanBeNull
FROM sampledata