2016-06-16 2 views
0

У меня есть таблица в моей базе данных, где у меня есть эти столбцы: [id, userId, locationId, created, update], и ​​я хочу, чтобы все пользователи были из местоположения в другое место, кроме пользователей, которые существуют во втором местоположении (и если эти новые записи могут иметь дату этой новой вставки в столбцах, созданных и обновленных, были бы фантастическими). Я имею в виду, если бы я имел эту таблицу:Вставить строки в таблицу из той же таблицы

id | userId | location | created | updated 
1 |  1 |  1 | 1234567 | 1234567 
2 |  2 |  1 | 9876543 | 9876543 
3 |  1 |  2 | 5555555 | 6666666 

Если предположить, что фактическое время 9999999, после операции вставки, результат должен быть таким:

id | userId | location | created | updated 
1 |  1 |  1 | 1234567 | 1234567 
2 |  2 |  1 | 9876543 | 9876543 
3 |  1 |  2 | 5555555 | 6666666 
4 |  2 |  2 | 9999999 | 9999999 

Любое решение ?? Благодарю.

EDIT (с учетом более случаев)

Существует еще некоторая информация, что я hadn't рассмотрел. Например, передача данных происходит только в одном направлении: информация идет от местоположения 1 к местоположению 2. В основном, потому что в местоположении 2, которое не было у местоположения 1, не было ни одного пользователя.
Идеальным решением было бы, что передача идет по двум направлениям, или даже с использованием более чем 2 места, что-то вроде этого:

id | userId | location | created | updated 
1 |  1 |  1 | 1234567 | 1234567 
2 |  2 |  1 | 9876543 | 9876543 
3 |  1 |  2 | 5555555 | 6666666 
4 |  3 |  2 | 1829384 | 0192837 
5 |  4 |  3 | 8888833 | 9991828 
6 |  5 |  4 | 1111111 | 2222222 

Предполагая, что фактическое время 9999999, И я хочу, чтобы включать только места 1, 2 и 3, после операции вставки, то результат должен быть таким:

id | userId | location | created | updated 
1 |  1 |  1 | 1234567 | 1234567 
2 |  2 |  1 | 9876543 | 9876543 
3 |  1 |  2 | 5555555 | 6666666 
4 |  3 |  2 | 1829384 | 0192837 
5 |  4 |  3 | 8888833 | 9991828 
6 |  5 |  4 | 1111111 | 2222222 
       /*news*/ 
7 |  3 |  1 | 9999999 | 9999999 
8 |  4 |  1 | 9999999 | 9999999 
9 |  2 |  2 | 9999999 | 9999999 
10 |  4 |  2 | 9999999 | 9999999 
11 |  1 |  3 | 9999999 | 9999999 
12 |  2 |  3 | 9999999 | 9999999 
13 |  3 |  3 | 9999999 | 9999999 

расположение 1, 2 и 3 доля их пользователей, но не место 4. Это может быть наилучшим решением, НО я бы согласился на то, что места делят свои данные с остальными один за другим ... и пр. ogrammatically я могу сделать петлю.

ответ

1

Что я сделал бы я, чтобы создать несколько столбцов уникального индекса по идентификатору пользователя - поля местоположения , Это предотвратит вставку повторяющихся идентификаторов пользователей для одного и того же местоположения.

Затем используйте запрос insert ignore ... select ..., чтобы вставить пользователей из другого места. Игнорирование означает, что MySQL будет игнорировать повторяющиеся ключевые ошибки запрещенных и продолжатель вставив правомерные пользователь:

INSERT IGNORE INTO yourtable (userId, location, created, update) 
SELECT userId, new_location, now(), now() 
FROM youtable as t2 
WHERE t2.location=current_location 

NEW_LOCATION и CURRENT_LOCATION являются параметрами, которые необходимо предоставить в запросе.

+0

Спасибо @Shadow, я немного боюсь, потому что это старый проект, и до сих пор эта таблица не использовала этот уникальный индекс ... Я думаю, что я использовал все возможности программно (с php), но я собираюсь спросите немного больше об ответе Giorgios в первом случае, и если я не смогу понять, я собираюсь сделать локальные тесты перед загрузкой. Спасибо. –

+0

Если вы хотите, чтобы пары userid - location были уникальными, самым простым способом является объявление уникального индекса для этих двух полей. В противном случае вам необходимо убедиться в том, что каждая часть кода проверяет уникальность данных перед обновлением таблицы. – Shadow

0

Вы можете использовать запрос вроде следующего:

INSERT INTO mytable (`userId`, `location`, `created`, `updated`) 
SELECT userId, IF(location = 1, 2, 1), NOW(), NOW() 
FROM mytable 
GROUP BY userId 
HAVING COUNT(DISTINCT location) = 1; 

Запрос предполагает, что id поле автоинкрементным и, таким образом, могут быть исключены из INSERT операции. Он также предполагает, что имеется только два доступных значения location, а именно 1 и 2.

+0

Я считаю, что вам нужно подписать mytable в избранной части, иначе это не сработает. – Shadow

+0

Здравствуйте, @Giorgios, я не уверен, если я пойму что-нибудь из вашего ответа, например: что означает 1, 2, 1 в «IF (location = 1, 2, 1)»? Что произойдет, если есть более доступное местоположение, но я хочу объединить только два? и если бы я объединил более двух мест? и последний вопрос Каково направление слияния? Я делаю редактирование, чтобы предоставить дополнительную информацию, если вы можете его избить, пожалуйста. Благодарю. –

+2

Если у вас более двух местоположений, то решение Giorgos не будет работать, потому что оно собирается объединить все остальные местоположения в одно из условий if. Как описано в его ответе, он предположил, что у вас всего 2 места. Функция if() описана в документации MySQL. – Shadow

0

Использование INSERT ....SELECT Statement

Для созданных и даты обновления вы можете использовать MySQL UNIX_TIMESTAMP() функцию

Подобно этому

INSERT INTO LOCATION2 (id, userId, locationId, created, update) 
SELECT id, userId, locationId, UNIX_TIMESTAMP(), UNIX_TIMESTAMP() FROM LOCATION1 
Смежные вопросы