如何将序列列添加并填充到链接表

时间:2011-08-16 15:04:32

标签: mysql sql sequence composite-key

假设我有一张如下表所示的表:

create table filetype_filestatus (
  id             integer(11) not null auto_increment,
  file_type_id   integer(11) not null,
  file_status_id integer(11) not null,
)

我想像这样添加一个序列列:

alter table filetype_filestatus add column sequence integer(11) not null;
alter table filetype_filestatus add unique key idx1 (file_type_id, file_status_id, sequence);

现在我想添加一个直截了当的列,并用一些满足唯一键的默认值填充它。

序列列允许用户任意为特定file_type命令file_status的显示。我不太关心初始订单,因为可以在应用程序中修改它。

理想情况下,我最终会得到类似的结果:

FileType FileStatus Sequence
   1        1          1
   1        2          2
   1        3          3
   2        2          1
   2        2          2

我能想到的最好的是:

update filetype_filestatus set sequence = file_type_id * 1000 + file_status_id;

有更好的方法吗?

2 个答案:

答案 0 :(得分:0)

如果您只需要“符合idx1的某些值”,为什么不复制id字段?毕竟,它是独一无二的......

UPDATE
  filetype_filestatus
SET
  sequence = id;

修改

如何根据所询问题的OP更改获取顺序值。

ROW_NUMBER()在MySQL中不可用,我也理解你也不能在源查询中使用正在更新的表。

create temporary table temp_filetype_filestatus (
  id             integer(11) not null auto_increment,
  file_type_id   integer(11) not null,
  file_status_id integer(11) not null,
  PRIMARY KEY (file_type_id, file_status_id)
)

INSERT INTO temp_filetype_filestatus (
  file_type_id,
  file_status_id
)
SELECT
  file_type_id,
  file_status_id
FROM
  filetype_filestatus
ORDER BY
  file_type_id,
  file_status_id

-- Update Option 1
------------------
UPDATE
  filetype_filestatus
SET
  sequence
  =
  (SELECT id FROM temp_filetype_filestatus
   WHERE file_type_id   = filetype_filestatus.file_type_id
     AND file_status_id = filetype_filestatus.file_status_id)
  -
  (SELECT id FROM temp_filetype_filestatus
   WHERE file_type_id   = filetype_filestatus.file_type_id
   ORDER BY file_status_id ASC LIMIT 1)
  +
  1

-- Update Option 2
------------------
UPDATE
  filetype_filestatus
SET
  sequence
  =
  (SELECT COUNT(*) FROM temp_filetype_filestatus
   WHERE file_type_id    = filetype_filestatus.file_type_id
     AND file_status_id <= filetype_filestatus.file_status_id)

答案 1 :(得分:0)

嗯,我相信这应该有效:

UPDATE filetype_filestatus as a 
       SET sequence = (SELECT COALESCE(MAX(b.sequence), 0)  
                       FROM filetype_filestatus as b
                       WHERE b.file_type_id = a.file_type_id) + 1

WHERE sequence = 0

我建议将新列添加到表中,运行alter table语句(并获取默认值0),运行update语句,然后添加约束(井,你必须反正)。触及的任何内容都会更新为大于0的sequence,因此也可以安全地运行多次。


修改

正如@Dems所指出的那样,子查询在更新之前运行,因此上述实际上并不适用于此目的。它适用于单行插入(这在这里没有任何帮助)。


修改

Gah,你有一个id列,这很好用(是的,我先测试过这个)。

UPDATE filetype_filestatus as a
       SET sequence = (SELECT COALESCE(COUNT(*), 0)
                       FROM filetype_filestatus as b
                       WHERE b.file_type_id = a.file_type_id
                       AND b.id < a.id) + 1
WHERE sequence = 0

不过,不了解性能影响。