powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / MySQL [игнор отключен] [закрыт для гостей] / Надо написать интересную команду INSERT SELECT
4 сообщений из 4, страница 1 из 1
Надо написать интересную команду INSERT SELECT
    #39179978
svnvlad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Существует две таблицы: договоры и грузы по договору (в одном договоре может быть несколько грузов).
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
CREATE TABLE `contract` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `contract_number` varchar(20) NOT NULL,
  `contract_date` datetime DEFAULT NULL,
  PRIMARY KEY (`id`) USING BTREE,
  UNIQUE KEY `contract_number` (`contract_number`)
)

CREATE TABLE `contract_cargo_head` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `contract_id` int(11) unsigned NOT NULL,
  `cargo_id` int(11) unsigned NOT NULL,
  `weight_contract_cargo` decimal(15,4) DEFAULT NULL,
  PRIMARY KEY (`id`) USING BTREE,
  CONSTRAINT `contract_cagro_fk1` FOREIGN KEY (`contract_id`) REFERENCES `contract` (`id`),
  CONSTRAINT `contract_cagro_fk2` FOREIGN KEY (`cargo_id`) REFERENCES `cargo_nomenclature` (`id`),
) 



Бизнес-модель изменилась, теперь появилась третья таблица - партии - consignment.
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
CREATE TABLE `consignment` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `contract_id` int(11) unsigned NOT NULL,
  `consignment_number` varchar(20) NOT NULL,
  `consignment_date` date DEFAULT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `consignment_idx1` (`contract_id`,`consignment_number`),
  KEY `contract_id` (`contract_id`),
  CONSTRAINT `consignment_fk1` FOREIGN KEY (`contract_id`) REFERENCES `contract` (`id`)
) 



Теперь для прошлых грузов надо создать задним числом партии по принципу: один груз по договору - одна партия. Для простоты будем делать id груза = id партии, на время выполнения запроса автоинкремент в таблице партий отключаем.
Код: sql
1.
2.
3.
4.
INSERT INTO consignment (id, contract_id, consignment_date, consignment_number)
SELECT cch.id, contract_id, contract_date, 1
FROM contract_cargo_head cch
INNER JOIN contract c ON c.id = cch.contract_id



Проблема в том, что в таблице партий есть поле Номер партии (consignment_number), и он формируется не по сквозной нумерации, а в пределах одного договора:
договор 1 - партия 1, партия 2, партия 3.
Договор 2 - партия 1, партия 2
Договор 3 - партия 1, партия 2, партия 3
и т.д.
Как составить запрос, чтобы consignment_number формировался по принципу 1,2,3, 1,2, 1,2,3 заново с каждым новым договором?
Видимо что-то такое, но как заставить @rownum обнуляться с каждым новым contract_id?
Код: sql
1.
2.
3.
4.
5.
INSERT INTO consignment (id, contract_id, consignment_date, consignment_number)
SELECT cch.id, contract_id, contract_date, (@rownum := @rownum + 1) AS rownum
FROM contract_cargo_head cch
INNER JOIN contract c ON c.id = cch.contract_id
JOIN (select @rownum := 0) AS r
...
Рейтинг: 0 / 0
Надо написать интересную команду INSERT SELECT
    #39179991
Фотография Akina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ничего интересного... всё, что надо - это прочитать FAQ: Нумерация строк и другие вопросы про использование переменных .
...
Рейтинг: 0 / 0
Надо написать интересную команду INSERT SELECT
    #39180075
svnvlad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AkinaНичего интересного... всё, что надо - это прочитать FAQ: Нумерация строк и другие вопросы про использование переменных .
Спасибо, подходит.
...
Рейтинг: 0 / 0
Надо написать интересную команду INSERT SELECT
    #39181152
svnvlad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Сработал следующий запрос!
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
INSERT INTO consignment (id, contract_id, consignment_date, consignment_number)
SELECT cch.id, cch.contract_id, contract_date,
IF(@cont_id=cch.contract_id, -- если "contract_id" не изменился
@rownum:=@rownum+1, -- то увеличить счетчик
@rownum:=1+least(0,@cont_id := cch.contract_id)) AS rown -- иначе скинуть счетчик на 1 
FROM contract_cargo_head cch
JOIN (select @rownum:=1, @cont_id:='_') zz
INNER JOIN contract c ON c.id = cch.contract_id
ORDER BY cch.contract_id, rown


Отлично, каждый раз при смене контракта счетчик номеров партии начинает работать с единицы.
...
Рейтинг: 0 / 0
4 сообщений из 4, страница 1 из 1
Форумы / MySQL [игнор отключен] [закрыт для гостей] / Надо написать интересную команду INSERT SELECT
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]