我有一个MySQL PHPMyAdmin数据库,在其中我意外地附加了两个相同的部分。对我来说,它们是重复的,但就实际数据而言,不是。 part_lists表中还有更多列:

+-----+---------------------------+----------+
| id  |        Part   Name        | Quantity |
+-----+---------------------------+----------+
|  1  | Part A (1/4")             |     0    |
|  2  | Part B                    |     3    |
|  3  | Part D                    |     4    |
|  4  | Part E                    |     9    |
| ... | a lot of part names later |    ...   |
| 95  | Part A (1/4") (0 free)    |     4    |  <-- newly appended
| 96  | Part B (-1 free)          |     5    |  <-- newly appended
| 97  | Part C (10 free)          |     1    |  <-- newly appended


表说明:

idunique编号,由表自动生成。 Quantity是库存零件数。 id#1id#95是相同的部分,但是id#95是更新的信息-即用于替换/更新id#1。该部分的末尾不应该有“ (0 free)”字符串,因此必须将其删除。 id#2id#96的情况也相同。 id#97是一个新的部分,我只需要删除最后的“ (10 free)”字符串即可。 id#3id#4是尚未更新的旧零件,因此应保留原样。

题:
我大部分(并非全部)附加的新零件在“ ([some number] free)”的末尾附加了一个“ Part”字符串。有时,这些部分是唯一的(即没有重复的部分)。问:如何去除重复项,但要确保信息已更新。问:这可以通过MySQL代码完成吗?如果没有,我将如何使用bash!

理想输出:

+-----+---------------------------+----------+
| id  |        Part   Name        | Quantity |
+-----+---------------------------+----------+
|  1  | Part A (1/4")             |     4    |  <-- Updated
|  2  | Part B                    |     5    |  <-- Updated
|  3  | Part D                    |     4    |
|  4  | Part E                    |     9    |
| ... | a lot of part names later |    ...   |
| 95  | Part C                    |     1    |  <-- newly appended


该列表将相对较短,因为附加的某些信息具有以前的更新条目。

最佳答案

这在MySQL中有点痛苦。标准SQL将使用exists

delete t
    from t
    where partname like '%(% free)' and
          not exists (select 1 from t t2 where t2.name like concat(t.name, '(% free)'));


或一些类似的逻辑。但是,MySQL不允许您引用被删除的表。因此,我认为您可以通过在substring_index()中使用join然后删除重复的行来查找重复项。但是,首先,您要更新值:

update t join
       t tfirst
       on tfirst.id < t.id and
          substring_index(t.partname, ' (', 1) = tfirst.partname and
          t.partname like '% (% free)'
    set tfirst.quantity = tfirst.quantity + t.quantity;


请注意,此公式仅适用于一个副本。如果有多个,则将为更新选择任意一个。

然后,您可以删除重复项:

delete t
    from t join
         t tfirst
         on tfirst.id < t.id and
            substring_index(t.partname, ' (', 1) = tfirst.partname and
            t.partname like '% (% free)';


然后,您要更新保留“ c”记录的零件名称:

update t
    set partname = substring_index(t.partname, ' (', 1)
    where t.partname like '% (% free)';

10-04 22:20
查看更多