【问题标题】:firebird 2.5 marking records with ordinal numberfirebird 2.5 用序号标记记录
【发布时间】:2017-06-22 10:03:44
【问题描述】:

我想用序号标记每个出现的特定记录。如果在“id”列中我有六倍相同的值,我需要将它们标记如下:第一次出现获得“1”,第二次获得“2”,第三次获得其他列中的“3”等。

提前感谢任何线索。

【问题讨论】:

  • 您是否坚持使用 Firebird 2.5,因为在 Firebird 3 中使用 row_number window function 是可能的。
  • 是的,我无法更新/迁移到 Firebird 3。

标签: firebird firebird2.5 ordinal


【解决方案1】:

使用 Firebird 3,您可以使用 row_number window function,例如:

select row_number() over (order by id, some_column), id, other_columns
from mytable

或者如果你想重新计算每个 id 值:

select row_number() over (partition by id order by some_column), id, other_columns
from mytable

如果您卡在 Firebird 2.5 上,您将不得不应用一些技巧来做到这一点:

一种选择是使用execute block(或存储过程)向结果集添加额外的递增值:

execute block
   returns (counter int, id int, other_columns varchar(32))
as
begin
    counter = 0;
    for select id, other_columns from mytable order by id, some_column into :id, :other_columns
    do
    begin
      counter = counter + 1;
      suspend;
    end
end

如果你想有类似partition by的效果,那么你需要跟踪id值,并在id值发生变化时重置计数器。

另一种选择是使用带有序列+触发器的临时表来添加唯一列。我也看到了使用递归 CTE 的解决方案,但我自己并不完全知道如何做到这一点(IIRC 你可能会遇到一些限制)。

或者,如果您只是在寻找一种唯一标识记录的方法,您可以添加 RDB$DB_KEY 伪列:

select rdb$db_key, id, other_columns 
from mytable 
order by id, some_column

rdb$db_key 唯一标识表中的记录(至少在事务期间)。

【讨论】:

  • 它有效(我使用了“执行块”解决方案)。非常感谢马克。
  • 只有一个古老的解决方案,使用没有 GTT 的生成器,但显然仅用于垄断使用。取消长选择的古老技巧也是:-D
猜你喜欢
  • 2017-05-29
  • 1970-01-01
  • 1970-01-01
  • 2015-07-19
  • 1970-01-01
  • 1970-01-01
  • 2012-07-08
  • 1970-01-01
  • 2011-07-07
相关资源
最近更新 更多