ОБНОВЛЕНИЕ с использованием JOIN добавляет только значение первой строки в другую таблицу, почему? - PullRequest
0 голосов
/ 09 октября 2018

У меня есть целевая таблица, которая пересекает 1 млн строк.Каждый раз я буду получать 50К строк, которые могут содержать несколько дублированных записей.Поэтому я решил сохранить данные CSV во временной таблице, затем из temp_table в target_table, сравнивая строки между двумя таблицами ...

Если найденные дублированные записи добавляют данные из temp_table в target_table, то еще Вставьте в таблицу ..Я использую раздел здесь, поэтому обновление ключа ON DUPLICATE здесь не работает .. в temp_table я не использую какие-либо KEYS

У меня есть две таблицы, которые выглядят как ниже

temp_table

Name |  Type
John |  Civil
John |  Mech

target_table

Name | Type
John | Civil

КогдаЯ запускаю запрос ниже, я получаю вывод из одной строки

 UPDATE target_table JOIN temp_table
 ON  temp_table.Name = target_table.Name
 SET target_table.Type = IF((LOCATE(temp_table.Type, target_table.Type) > 0) 
 target_table.Type,CONCAT(target_table.Type,',',temp_table.Type))


target_table

Name | Type
John | Civil

Я ожидаю, что результат будет как ниже

target_table

Name | Type
John | Civil, Mech

Могу ли я знать, где это пошло не так?

Ответы [ 2 ]

0 голосов
/ 09 октября 2018

Я подозреваю (но не знаю наверняка), и, надеюсь, кто-то, кто знает, подскакивает и исправляет меня, что объединение обновлений не создает декартово произведение, как это делает выбор.В качестве попытки доказательства

truncate table temp_table;
insert into temp_table values
( 'John' , 'mech' ),
( 'John' , 'abc'  );
truncate table target_table;
insert into target_table values
('john', 'civil', 9 );

UPDATE target_table JOIN temp_table
ON  temp_table.Name = target_table.Name
set target_table.type = (concat(target_table.Type,',',temp_table.Type));

select * from target_table;

+------+------------+------+
| Name | Type       | LOC  |
+------+------------+------+
| john | civil,mech |    9 |
+------+------------+------+
1 row in set (0.00 sec)

обратите внимание, что abc из temp_table игнорируется и мех выбирается чисто случайно.

, если мы изменим порядок в temp_table

truncate table temp_table;
insert into temp_table values
( 'John' , 'abc' ),
( 'John' , 'mech'  );
truncate table target_table;
insert into target_table values
('john', 'civil', 9 );

UPDATE target_table JOIN temp_table
ON  temp_table.Name = target_table.Name
set target_table.type = (concat(target_table.Type,',',temp_table.Type));

select * from target_table;

мы получаем

+------+-----------+------+
| Name | Type      | LOC  |
+------+-----------+------+
| john | civil,abc |    9 |
+------+-----------+------+
1 row in set (0.02 sec)

, где abc выбирается чисто случайно.

На мой взгляд, самый безопасный способ сделать это - строка за строкой, то есть курсор.

0 голосов
/ 09 октября 2018

вы должны использовать group_concat и использовать подзапрос в объединении

 UPDATE target_table 
 JOIN (
    select name, group_concat(Type) grouped
    from temp_table 
    group by name
 ) t ON t.Name = target_table.Name
 SET target_table.Type = t.grouped
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...