【问题标题】:How to append an auto-incrementing value to a duplicate value?如何将自动递增值附加到重复值?
【发布时间】:2017-05-14 02:13:35
【问题描述】:

我有权访问我们每天从云服务中检索并存储在 mysql 数据库中的报告数据集(我无法控制),以运行高级报告并在本地与第三方数据可视化软件相结合。

数据通常在 id 字段上具有重复值,这在与其他表连接进行数据分析时会产生问题。

例如:

 +-------------+----------+------------+----------+
 | workfile_id | zip_code |    date    |   total  |
 +-------------+----------+------------+----------+
 |       78002 |    90210 | 2016-11-11 | 2010.023 |
 |       78002 |    90210 | 2016-12-22 |  427.132 |
 +-------------+----------+------------+----------+

Workfile_id 重复,因为这是同一个作业,但该作业的其他工作是在与原始工作不同的月份执行的。软件不会为作业创建另一个工作文件 ID,而是使用相同的 ID。

当存在多个相同的 id 时,在 workfile_id 上与其他表进行联接是有问题的,所以我想知道是否可以做以下两件事之一:

  1. 使重复的 workfile_id 唯一。 找到重复项时,让 sql 将数字附加到工作文件 id。第一次重复(或第二次出现相同的工作文件 ID)需要在工作文件 ID 的末尾附加一个 .01。稍后,如果插入另一个副本,则需要自动增加附加的数字,例如 .02,以此类推,并使用任何后续重复的 workfile_id。这种方法最适合我们的数据,但我很好奇从性能角度来看这对服务器来说有多困难。如果我可以安排在插入数据后进行更改以加快初始数据插入,那将是理想的。
  2. 汇总总列并删除重复的 workfile_id 行。 有一个任务来识别重复的 workfile_ids 并对重复项的财务列进行求和,用新的总和替换原始总和并在列删除后删除“新行”被加在一起了。 从数据保存的角度来看,这更加混乱,但如果第一个解决方案不可行,则可以接受。

我的假设是每次插入数据时让服务器将新的 workfile_id 值与所有现有的 worlfile_id 值进行比较会有很大的开销,但是我们的数据集很小,并且每天只在凌晨 1:30 插入一次新数据,并且将重复的 workfile_id 搜索到最近 6 个月内插入的行也应该是可行的。

是否可以在列 (workfile_id) 中查找重复项将自动递增值附加到 workfile_id 上?

编辑: 根据下面 sdsc81 的回答,我无法让触发器工作。 有什么想法吗?

DELIMITER //

CREATE TRIGGER append_subID_to_workfile_ID_salesjournal
AFTER INSERT
   ON salesjournal FOR EACH ROW

BEGIN
   SET @COUNTER = ( SELECT (COUNT(*)-1) FROM salesjournal WHERE workfile_id = NEW.workfile_id );
   IF @COUNTER > 1 THEN
       UPDATE salesjournal SET workfile_id = CONCAT(workfile_id, @COUNTER) WHERE id = NEW.id;
   END IF;

END;//

DELIMITER ;

很难知道触发器是根本不工作,还是只是触发器中的代码不工作。我在插入时没有错误。有没有办法调试触发错误?

【问题讨论】:

    标签: mysql duplicates append auto-increment


    【解决方案1】:

    好吧,一切皆有可能;)

    你不控制数据集,但你可以修改数据库,对吧? 然后,您可以在每次插入新值之后使用触发器,如果重复,则更新它。比如:

    SET @COUNTER = ( SELECT (COUNT(*)-1) FROM *your_table* WHERE workfile_id = NEW.workfile_id );
    IF @COUNTER > 1 THEN
        UPDATE *your_table* SET workfile_id = CONCAT(workfile_id, @COUNTER) WHERE some_unique_id = NEW.some_unique_id;
    END IF;
    

    如果一天只有一个插入,并且在 workfile_id 值上定义了一个索引,那么这对您的服务器应该没有任何问题。

    另外,您可以实施第二个解决方案,这样做:

    DELIMITER //
    
    CREATE TRIGGER append_subID_to_workfile_ID_salesjournal
    AFTER INSERT ON salesjournal FOR EACH ROW
    
    BEGIN
    SET @COUNTER = ( SELECT (COUNT(*)-1) FROM salesjournal WHERE workfile_id = NEW.workfile_id );
    IF @COUNTER > 1 THEN
        UPDATE salesjournal SET total = total + NEW.total WHERE workfile_id = NEW.workfile_id AND id <> NEW.id;
        DELETE FROM salesjournal WHERE id = NEW.id;
    END IF;
    
    END;//
    
    DELIMITER ;
    

    希望这会有所帮助。

    【讨论】:

    • 如果您需要添加的值是 2 位数字,那么您可以在 UPDATE your_table ... 指令之前使用 SET @COUNTER = CONCAT( '0', @COUNTER ); 然后 SET @COUNTER = SUBSTR( @COUNTER, LENGTH( @COUNTER - 1)); 之类的内容。这很乱,但应该做的伎俩。干杯
    • 是的,如果我不清楚,我很抱歉。我完全控制目标数据库。我不是贸易数据库管理员,所以我不清楚如何完成这样的事情。我今天被淹没了,但我会尽快测试你的方法,如果成功的话,我会选择它为正确的。感谢您的快速回复。
    • 嗨!我仔细检查了一下,发现我更正了查询。顺便问一下,表中的所有字段都是这样吗?或者你有一个独特的 id 来标识每一行? (我的意思是,就像一个自动增量值).. 因为这需要正常工作。告诉我。
    • 抱歉,不,这些不是所有字段。我只是想保持简单。我确实有一个自动递增的唯一 id 字段。我已经用你更新的代码更新了我的触发器,我现在正在测试它。手指交叉。
    • 太棒了!然后你必须在 where 子句中设置那个 IDWHERE unique_id = NEW.unique_id。否则它将更新所有包含 workfile_id 值的字段。
    猜你喜欢
    • 2022-07-25
    • 1970-01-01
    • 2020-06-18
    • 1970-01-01
    • 2013-08-19
    • 2021-05-25
    • 2010-10-04
    • 2018-01-01
    • 2015-10-17
    相关资源
    最近更新 更多