【问题标题】:Computed column formula for row_number functionrow_number 函数的计算列公式
【发布时间】:2020-11-16 04:59:03
【问题描述】:

我正在尝试为计算列找到一个公式,该公式将返回与ROW_NUMBER() 函数相同的结果。因为我不能使用ROW_NUMBER() 函数并将结果保存在表格中。 我有一张如下表;

ID  YEAR  
1   2018      
2   2018      
3   2019      
4   2019      
5   2020      
6   2018      
7   2019      

我想要一个公式来计算和分配取决于年份的行数,如下所示;

ID     YEAR     COMPUTED COLUMN
1      2018     1
2      2018     2  
3      2019     1  
4      2019     2  
5      2020     1  
6      2018     3  
7      2019     3  

【问题讨论】:

  • 为什么不能不使用行号?
  • 您确定要查找计算列吗?即在您的表定义中定义的列?还是您的查询只需要一个计算列?
  • row_number 函数不能在表中使用,我希望将结果保存在表中的列中

标签: sql sql-server window-functions calculated-columns sql-view


【解决方案1】:

我正在尝试为计算列找到一个公式,该公式将返回与 ROW_NUMBER() 函数相同的结果。

您不能在计算列中使用窗口函数;窗口函数对一系列行(称为窗口框架)进行操作,而计算列仅对其所属的行可见。

我无法使用 ROW_NUMBER() 函数并将结果保存在表格中

虽然这在技术上是可行的,但我不建议这样做。这是派生信息,可以在需要时即时计算。您可以改用视图:

create view myview
as
select
    id, 
    year,
    row_number() over (partition by year order by id) rn
from mytable

【讨论】:

  • 我已经创建了视图,但我意识到我不能在我的应用程序中使用视图中的数据
【解决方案2】:

总有办法绕过它。

虽然这不是一个好方法......

select
    id, 
    year,
    row_number() over(partition by year order by id) rn,
    (select count(*) from Table1 t where t.YEAR=d.YEAR and t.ID<=d.ID) PoorRN
from Table1 d
order by id

• 这将有一个非常糟糕的表现。 如果您的表有超过一百万行 - 只需在生产中继续并告诉我们发生了什么;)

【讨论】:

    【解决方案3】:

    更新:根据 OP 的 cmets,我有一个新建议 -

    1. 从原始表格 - 创建一个视图,然后为每年指定数字

      创建视图 original_table_view 作为 select *, ROW_NUMBER() over (partition by [year] order by ID) 作为编号 来自 original_table

    2. 创建一个新表并从视图中对新表应用合并

      创建表New_table(id int,[year] int,numbering int)

    创建合并语法 -

    merge new_table t using original_table_view v
    on (t.id = v.id) --merge_condition 
    when matched then update set 
    t.[year]=v.[year],
    t.numbering=v.numbering
    when not matched by target
    then insert ( id, [year], numbering)
    values (v.id, v.[year],numbering)
    when not matched by source
    then delete;
    

    现在,如果将来,如果在原始表中插入新值,您只需要运行合并查询来更新新表。

    查看数据-

    select * from original_table order by ID
    select * from original_table_view order by ID
    select * from New_table order by ID
    

    旧答案: 我将您的查询与计算列而不是计算列混淆了(抱歉)

    您不能将函数存储为 SQL 服务器中的计算列。但是,您可以在表上创建一个视图,然后调用它。

    例子-

    如下创建表

    create table year_computed2 (ID int, Year int )
    go
    
    insert into year_computed2 values (1,2018 )
    insert into year_computed2 values (2,2018 )
    insert into year_computed2 values (3,2019 )
    insert into year_computed2 values (4,2019 )
    insert into year_computed2 values (5,2020 )
    insert into year_computed2 values (6,2018 )
    insert into year_computed2 values (7,2019 )
    go
    

    现在使用 Row_number() 函数创建一个视图(您也可以使用 Rank() 和 Ntile())

    alter view year_computed_view as
    select *, ROW_NUMBER() over ( partition by [year] order by ID) as Rn from year_computed2 
    

    现在像下面这样查询这个视图

    select * from year_computed_view order by ID
    

    enter image description here


    如果您在谈论计算列 - 下面的答案是 可用


    Dense_Rank()

    select DISTINCT id, [year], DENSE_RANK() over ( order by [year]) as [Dense_rank]
    from year_computed
    ORDER BY ID
    

    输出如下:

    如果 Dense_rank 不满足,请尝试以下两个功能 -

    1. 排名()

      select DISTINCT id, [year], RANK() over (partition by [year] order by ID) as [Rank] 从 year_computed 按 ID 订购

    enter image description here

    1. NTile()

      declare @ntile_count int = (select count (distinct [year])from year_computed) select id, [year], ntile(@ntile_count) over (partition by [year] order by id) as rn from year_computed ORDER BY ID

    enter image description here

    【讨论】:

    • select id, [year], rank() over (partition by [year] order by id) as rn from year_computed ORDER BY ID rank() 也给出与您共享的表完全相同的结果。如果 rank() 也不允许,那么不妨也添加这些有问题的函数
    • 或者声明@ntile_count int = (select count (distinct [year])from year_computed) select id, [year], ntile(@ntile_count) over (partition by [year] order by id) as rn from year_computed ORDER BY ID 使用这个
    • 没关系,只是想帮忙。事实上,创建视图也是没有意义的,因为无论如何您都没有使用计算列。因此我下面的两个建议仍然有效。 :-)
    • 获得 ROW_NUMBER 结果不是问题,我可以通过查询或 viev 来完成,问题是将这些结果移动到表中
    • 但是,如果您创建一个新表并插入视图中的所有值,它应该可以工作。只是你的表中不会有计算列。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-04-11
    • 1970-01-01
    • 2018-08-07
    • 1970-01-01
    • 2011-05-18
    • 2014-08-09
    • 1970-01-01
    相关资源
    最近更新 更多