2013-11-27 5 views
1

Все, У меня есть таблица mySQL с двумя полями, old и new. Каждый содержит строку в следующем формате:MySQL получить разницу между двумя строковыми полями

key1=value1, key2=value2, key3=value3

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

Возможно ли иметь еще два столбца, которые сравнивают значения в old и new и выдает только те пары ключ/значение, которые отличаются?

old       | new       | diff_old   | diff_new 
key1=xxx, key2=yyy, key3=zzz | key1=xxx, key2=aaa, key3=zzz | key2=yyy   | key2=aaa 
keya=xxx, keyb=yyy, keyc=zzz | keya=111, keyb=yyy, keyc=222 | keya=xxx, keyc=zzz| keya=111, keyc=222 

Im известен SUBSTRING_INDEX может быть использован для разделения строк, однако вопрос различающегося пар ключа/значения между строками, что означает функция не может быть приготовлена ​​так легко.

+2

Строка компонент это делает его значительно более сложной ... любая воля, чтобы нормализовать значения там (поэтому key1, key2 и key3 являются отдельными полями)? Комбинация подстроки и charindex, чтобы выбрать значение для каждого ключа, а затем сравнить то, что он выбирает, очень возможно, просто не так весело писать ... много проб и ошибок. – Twelfth

+1

Является ли список возможных ключей известными и статичными? Вы ищете что-то вроде реализации MySQL http://en.wikipedia.org/wiki/Longest_common_subsequence_problem? Это одноразовое задание или вы хотите, чтобы столбцы 'diff_old' и' diff_new' были заполнены, так как новые строки добавляются в эту таблицу? – yegeniy

ответ

0

Используемый ниже запрос, дает точный результат. Я дважды проверить мои результаты:

Таблица структуры:

CREATE TABLE `try` (
    `old` varchar(200) DEFAULT NULL, 
    `new` varchar(200) DEFAULT NULL, 
    `old_diff` varchar(200) DEFAULT NULL, 
    `new_diff` varchar(200) DEFAULT NULL 
) ENGINE=InnoDB DEFAULT CHARSET=latin1 

Запрос:

SELECT CONCAT(IF(aa.first_string!=aa.first_string1,first_string,''), 
IF(aa.middle_string!=aa.middle_string1,middle_string,'') , 
IF(aa.last_string!=aa.last_string1,last_string,'')) AS first_result, 
CONCAT(IF(aa.first_string!=aa.first_string1,first_string1,''), 
IF(aa.middle_string!=aa.middle_string1,middle_string1,'') , 
IF(aa.last_string!=aa.last_string1,last_string1,'')) AS second_result 
FROM (SELECT SUBSTRING_INDEX(SUBSTRING_INDEX(`old`, ',', 1), ',', -1) 
AS first_string, 
IF( LENGTH(`old`) - LENGTH(REPLACE(`old`, ',', ''))>1, 
SUBSTRING_INDEX(SUBSTRING_INDEX(`old`, ',', 2), ',', -1) ,NULL) AS middle_string, 
SUBSTRING_INDEX(SUBSTRING_INDEX(`old`, ',', 3), ',', -1) AS last_string, 
SUBSTRING_INDEX(SUBSTRING_INDEX(`new`, ',', 1), ',', -1) AS first_string1, 
IF( LENGTH(`old`) - LENGTH(REPLACE(`new`, ',', ''))>1, 
SUBSTRING_INDEX(SUBSTRING_INDEX(`new`, ',', 2), ',', -1) ,NULL) AS middle_string1, 
SUBSTRING_INDEX(SUBSTRING_INDEX(`new`, ',', 3), ',', -1) AS last_string1 
FROM try) aa 
Смежные вопросы