powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / MySQL [игнор отключен] [закрыт для гостей] / Аналог merge в MySQL
4 сообщений из 4, страница 1 из 1
Аналог merge в MySQL
    #38669274
Alibek B
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Есть у меня такая таблица:
Код: sql
1.
2.
3.
4.
5.
6.
CREATE TABLE `REQUESTS` (
	`USER` VARCHAR(80) NOT NULL,
	`COUNT` INT(10) UNSIGNED NOT NULL,
	`LAST` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
	PRIMARY KEY (`USER`)
)



Мне нужно при получении запроса от USER сделать следующее:
1. Если в таблице нет такого USER, добавить новую запись с COUNT=1.
2. Если в таблице есть такой USER и LAST<DATE_FORMAT(CURRENT_TIMESTAMP(), '%Y-%m-01'), то обновить у найденной записи COUNT=1 и LAST=CURRENT_TIMESTAMP().
3. Если в таблице есть такой USER и LAST>=DATE_FORMAT(CURRENT_TIMESTAMP(), '%Y-%m-01'), то обновить у найденной записи COUNT=COUNT+1 и LAST=CURRENT_TIMESTAMP().

Насколько я понимаю, описание столбца "DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP" решает вопрос обновления поля LAST.
Но остается вопрос обновления/добавления поля COUNT, я бы хотел это сделать в один запрос. С помощью MERGE это сделать можно — в предложении WHEN MATCHED я делаю UPDATE, в предложении WHEN NOT MATCHED я делаю INSERT.
Но вот с синтаксисом MySQL мне непонятно, как получить такой же результат.
Составил такой запрос:
Код: sql
1.
2.
insert into REQUESTS (USER, COUNT) values (?, 1)
on duplicate key update COUNT = case when LAST<DATE_FORMAT(CURRENT_TIMESTAMP(), '%Y-%m-01') then 1 else COUNT+1 end


Но не совсем уверен в его правильности, просьба поправить.

________________________
Мы смотрим с оптимизмом...
...в оптический прицел.
...
Рейтинг: 0 / 0
Аналог merge в MySQL
    #38669467
Cygapb-007
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Alibek B.,

моё ЯТД:
1) не совсем ясен ПК на длинную строку USER. То есть для этой задачи он оптимален, но как ссылка - int, вероятно, все же лучше. А на USER (конкретно для этой задачи) достаточно навесить NOT NULL UNIQUE
2) не верно реализован алгоритм: возможен случай, когда дата перестанет изменяться (в прошлом месяце было одно посещение, тогда при каждом посещении в новом месяце изменения 1 от старого на 1 из нового не произойдет, UPDATE не будет отработано и дата не изменится). Как минимум, в секции UPDATE нужно дописать LAST=CURRENT_TIMESTAMP(). Пруф - по ссылке: ник USR1.
3) добавление (если возможно несколько точек в коде, в т.ч. отладочных) можно оформить процедурой вроде этой ( http://sqlfiddle.com/#!2/c03a3/2 ):
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
create procedure ins(usr VARCHAR(80))
begin
insert into REQUESTS (USER, COUNT) values (usr, 1)
on duplicate key update 
  COUNT = case when LAST<DATE_FORMAT(CURRENT_TIMESTAMP(), '%Y-%m-01') 
    then 1 else COUNT+1 end,
  LAST = case when LAST<DATE_FORMAT(CURRENT_TIMESTAMP(), '%Y-%m-01') 
    then CURRENT_TIMESTAMP() else LAST end;
end;
...
Рейтинг: 0 / 0
Аналог merge в MySQL
    #38669502
Alibek B
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
1. USER у меня это идентификатор пользователя. В основном это будет номер телефона, но иногда это будет email. Есть какая-то выгода сделать его не PK, а просто уникальным ключом?
2. То есть если я сделаю update ... set count=count, то обновления не произойдет, поскольку новое и старое значения совпадают? Ок, запрос подправлю.
3. Я никак не привыкну, что в MySQL наконец добавили ХП.
...
Рейтинг: 0 / 0
Аналог merge в MySQL
    #38669551
Cygapb-007
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Alibek B.,

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


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