Как добавить и заполнить столбец последовательности в таблице ссылок - PullRequest
1 голос
/ 16 августа 2011

Предполагая, что у меня есть таблица, подобная приведенной ниже:

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_status для определенного file_type. Я не слишком обеспокоен начальным порядком, поскольку он может быть изменен в заявке.

В идеале я хотел бы получить что-то вроде:

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 голосов
/ 16 августа 2011

Хм, я считаю, что это должно работать:

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), выполнить оператор обновления, затем добавить ограничение (ну, у вас есть в любом случае). Все, что касается прикосновения, обновляется до sequence больше 0, поэтому его можно безопасно запускать несколько раз.

<Ч />

EDIT:

Как указал @Dems, подзапрос запускается перед обновлением, поэтому вышеприведенное фактически не работает для этой цели. Он работает на однострочных вставках (что совсем не помогает).

<Ч />

EDIT:

Гах, у вас есть столбец 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

Не знаю, как это влияет на производительность.

0 голосов
/ 16 августа 2011

Если вам нужны только «некоторые значения, соответствующие idx1», почему бы просто не скопировать поле id?В конце концов, это уникальный ...

UPDATE
  filetype_filestatus
SET
  sequence = id;

РЕДАКТИРОВАТЬ

Как получить последовательные значения, основанные на ОП, изменяет задаваемый вопрос.

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)
...