Как добавить идентификатор автоинкремента в соответствии с группой в mysql

Вот формат таблицы:

indexer group name id
1       abc   a
2       abc   b
3       xyz   c
4       abc   e
5       xyz   d

Теперь я хочу, чтобы это было так,

indexer group name id
1       abc   a    1
2       abc   b    2
3       xyz   c    1
4       abc   e    3
5       xyz   d    2

«id» должен автоматически увеличиваться в соответствии с «group»


person Heider Kumar    schedule 03.08.2016    source источник
comment
Невозможно в MySQL. Вы можете написать хранимую процедуру для выполнения INSERT, которая вычисляет следующий идентификатор, но вам, вероятно, лучше сгенерировать последовательность извне; в любой программе, которую вы используете для вставки данных.   -  person Boris the Spider    schedule 03.08.2016
comment
В любом случае, это не имеет особого смысла, что именно вы пытаетесь сделать?   -  person polku    schedule 03.08.2016
comment
Ой!! Где это будет возможно?   -  person Heider Kumar    schedule 03.08.2016
comment
На самом деле у меня большая база данных, которую невозможно сделать вручную. Поэтому я подумал, есть ли другой способ сделать это.   -  person Heider Kumar    schedule 03.08.2016
comment
Итак, вы хотите добавить столбец в свою таблицу?   -  person Blank    schedule 03.08.2016
comment
Я думаю, я могу сделать это с помощью запроса mysql. Сначала я сделаю запрос в соответствии с группой через последовательный порт i++ и соответствующим образом обновлю идентификатор таблицы.   -  person Heider Kumar    schedule 03.08.2016
comment
@JPG У меня уже был идентификатор столбца в таблице, который сейчас равен нулю. Я хочу добавить серийные номера к идентификатору столбца в соответствии с группой.   -  person Heider Kumar    schedule 03.08.2016


Ответы (2)


Попробуй это:

update yourtable t1
join (
    select
          tt.indexer, @rowno := if(@grp = `group`, @rowno + 1, 1) as id, @grp := `group`
    from (select * from yourtable order by `group`, indexer) tt
    cross join (select @rowno := 0, @grp := null) t
) t2
on t1.indexer = t2.indexer
set t1.id = t2.id

Демо здесь

Отредактировано:

Если вы хотите вставить новую строку, вы должны сделать это следующим образом:

insert into yourtable
select '$indexer', '$group', '$name', coalesce(max(id), 0) + 1
from yourtable
where name = '$name'
person Blank    schedule 03.08.2016
comment
Позже, когда я вставлю новую строку, будет ли идентификатор автоматически вставлять номер или мне придется снова запускать код? - person Heider Kumar; 03.08.2016
comment
@HeiderKumar Проверьте часть Отредактировано. - person Blank; 03.08.2016
comment
@HeiderKumar Обратите внимание, что способ вставки новых строк не работает. Он ничего не вставит, если выбор не найдет запись в таблице. Также имейте в виду, что это решение будет иметь ужасную производительность, когда у вас много данных. Он всегда будет выполнять полное сканирование таблицы. - person fancyPants; 03.08.2016
comment
Еще один недостаток заключается в том, что при интенсивном трафике в вашей базе данных может случиться так, что несколько записей будут иметь один и тот же идентификатор. - person fancyPants; 03.08.2016
comment
@fancyPants Все, что вы сказали, совершенно верно, но здесь просто как некое решение. Иногда мы даем ответ, тогда он находит, что это может решить его проблему, оно есть. Конечно, я уважаю ваши усилия по вашему ответу и многому научился из него. - person Blank; 03.08.2016

Если вы хотите использовать встроенную функцию, вы должны использовать таблицу MyISAM. Имейте в виду, однако, что они не поддерживают транзакции и используют блокировки на уровне таблицы и так далее. Возможно, вы захотите прочитать об этом. Если вас это устраивает, вот как. Если вы хотите использовать InnoDB или другие механизмы, вам придется написать собственное решение, то есть хранимую процедуру.

Цитата из руководства:

Для таблиц MyISAM можно указать AUTO_INCREMENT для вторичного столбца в многостолбцовом индексе. В этом случае сгенерированное значение для столбца AUTO_INCREMENT вычисляется как MAX(auto_increment_column) + 1 WHERE prefix=given-prefix. Это полезно, когда вы хотите поместить данные в упорядоченные группы.

CREATE TABLE animals (
    grp ENUM('fish','mammal','bird') NOT NULL,
    id MEDIUMINT NOT NULL AUTO_INCREMENT,
    name CHAR(30) NOT NULL,
    PRIMARY KEY (grp,id)
) ENGINE=MyISAM;

INSERT INTO animals (grp,name) VALUES
    ('mammal','dog'),('mammal','cat'),
    ('bird','penguin'),('fish','lax'),('mammal','whale'),
    ('bird','ostrich');

SELECT * FROM animals ORDER BY grp,id;

Which returns:

+--------+----+---------+
| grp    | id | name    |
+--------+----+---------+
| fish   |  1 | lax     |
| mammal |  1 | dog     |
| mammal |  2 | cat     |
| mammal |  3 | whale   |
| bird   |  1 | penguin |
| bird   |  2 | ostrich |
+--------+----+---------+
  • В этом случае (когда столбец AUTO_INCREMENT является частью индекса с несколькими столбцами) значения AUTO_INCREMENT используются повторно, если вы удаляете строку с самым большим значением AUTO_INCREMENT в любой группе. Это происходит даже для таблиц MyISAM, для которых значения AUTO_INCREMENT обычно повторно не используются.

  • Если столбец AUTO_INCREMENT является частью нескольких индексов, MySQL генерирует значения последовательности, используя индекс, который начинается со столбца AUTO_INCREMENT, если он есть. Например, если бы таблица животных содержала индексы PRIMARY KEY (grp, id) и INDEX (id), MySQL проигнорировал бы PRIMARY KEY для генерации значений последовательности. В результате таблица будет содержать одну последовательность, а не последовательность для каждого значения группы.

person fancyPants    schedule 03.08.2016