【问题标题】:Incremental count column based on another column contents基于另一列内容的增量计数列
【发布时间】:2009-07-23 15:12:54
【问题描述】:

我需要使用基于另一列内容的运行计数填充一列。表格是这样的:

计数 seq_num 1 123-456-789 1 123-456-780 1 123-456-990 2 123-456-789 2 123-456-990

因此,随着 seq_num 列的变化,计数器重置为“1”,并且随着列重复,计数器增加 1。

这里使用的是SQL2000,seq_num字段为varchar。

有什么想法吗?

【问题讨论】:

  • 这是用于插入还是事后?如果事后发生,我们怎么知道先添加了什么?

标签: sql sql-server sql-server-2000


【解决方案1】:

如果要插入,可以使用子查询:

insert into 
    table (count, seq_num) 
values 
    ((select count(*)+1 from table where seq_num = @seq)
    ,@seq)

否则,您需要在上面注明日期或以某种方式告诉它如何确定什么是第一个:

update table 
set count = 
    (select count(*)+1 from table t2 
     where t2.seq_num = table.seq_num 
           and t2.insertdate < table.insertdate)

【讨论】:

  • 哪个 seq_num 先发生是无关紧要的。第一个例子看起来不错。我会试一试。感谢您的回复..非常感谢。
  • OK..尝试了第一个查询,但我确实需要更新,而不是插入。该表具有计数字段,但需要根据 seq_num 的出现来填充它。所以我尝试了第二个,但我没有第二个表可以参考。此外,seq_nums 发生的日期是无关紧要的。
【解决方案2】:

如果您以后需要继续更新此内容,您可以试试这个。这是几个步骤,但会修复它并设置它以供将来使用。 (可能需要检查我的语法 - 我现在更多地使用 ORacle,所以我可能混淆了一些东西 - 但逻辑应该有效。)

首先,创建一个表来包含每个序列的当前计数器级别:

Create newTable (counter int, sequence varchar)

然后,用这样的数据填充它: 插入新表 (选择不同的0作为计数器,序列 从表) 这会将每个序列号放入表中一次,每个序列号的计数器将设置为 0。

然后,使用两个更新语句和一些额外的逻辑创建一个更新过程:

Create procedere counterUpdater(@sequence varchar) as

Declare l_counter as int;
select l_counter = counter
from newTable
where sequence = @sequence

--assuming you have a primary key in the table.
Declare @id int;
Select top 1 @id = id from table 
where sequence = @sequence
   and counter is null;

--update the table needing edits.
update table 
set counter = l_counter + 1
where id = @id

--update the new table so you can keep track of which 
--counter you are on
update newTable
set counter = l_counter + 1
where id = @id

然后运行一个 proc 来为表中的每条记录执行这个 proc。

现在您应该有一个“newTable”,其中填充了表中每条记录当前使用的计数器。设置您的插入过程,以便在任何时候创建新记录时,如果它是尚未在 newTable 中的序列,则将其添加为 1,并将计数 1 放入主表中。如果序列确实存在,请使用上述逻辑(增加已使用“newTable”的计数,并将该计数作为计数器值放在 newTable 和 mainTable 中。

基本上,此方法决定使用内存来代替查询现有表。如果您有一个包含大量重复序列号的大表,这将变得最有益。如果您的序列号只出现两到三次,您可能希望在更新然后插入时进行查询:

首先,更新: --找出计数器值 声明 l_counter int 选择 l_counter = 最大值(计数器) 从表中序列 = @sequence

update table 
set counter = l_counter + 1
where id = (select top 1 id from table where sequence = @sequence
            and counter is null)

然后为每条记录运行它。

那么,在插入新记录时:

Declare l_counter int
select l_counter = max(counter)
from table where sequence = @sequence

IsNull(l_counter, 0)

Insert into table
(counter, sequence) values (l_counter + 1, @sequence)

再次,我很肯定我在这里混合并匹配了我的语法,但这些概念应该有效。当然,这是一种“一次一个”的方法,而不是基于集合的方法,所以它可能效率有点低,但它会起作用。

【讨论】:

    猜你喜欢
    • 2017-09-30
    • 1970-01-01
    • 1970-01-01
    • 2010-12-23
    • 2021-07-15
    • 2018-02-18
    • 1970-01-01
    • 2022-10-24
    • 2011-09-04
    相关资源
    最近更新 更多