У меня есть таблица tbl1
с двумя столбцами col1
и col2
, содержащая строки:
col1 | col2
--------+--------
bar | foo
foo | foobar
bar1foo | bar2foo
Соответствующий дамп SQL:
CREATE TABLE `tbl1` (
`col1` varchar(20) COLLATE latin1_general_ci NOT NULL,
`col2` varchar(20) COLLATE latin1_general_ci NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci;
INSERT INTO `tbl1` (`col1`, `col2`) VALUES
('bar', 'foo'),
('foo', 'foobar'),
('bar1foo', 'bar2foo');
Строки записиразделяют общий префикс в большинстве случаев. Мне нужен запрос, который удаляет эти общие префиксы. Ожидаемый результат:
bar | foo
| bar
1foo | 2foo
Мой подход на данный момент:
SELECT
SUBSTR(`col1`, 1+GREATEST(LENGTH(`col1`), LENGTH(`col2`)) - CEIL(LENGTH(TRIM(TRAILING '0' FROM HEX(ABS(CONV(HEX(REVERSE(`col1`)),16,10) - CONV(HEX(REVERSE(`col2`)),16,10)))))/2)),
SUBSTR(`col2`, 1+GREATEST(LENGTH(`col1`), LENGTH(`col2`)) - CEIL(LENGTH(TRIM(TRAILING '0' FROM HEX(ABS(CONV(HEX(REVERSE(`col1`)),16,10) - CONV(HEX(REVERSE(`col2`)),16,10)))))/2))
FROM tbl1
Краткое объяснение: строки поменялись местами (REVERSE
), преобразованы в целые числа (HEX
и * 1018)*) вычитаются друг из друга (-
и ABS
), преобразуются в шестнадцатеричное представление (HEX
), 0
обрезаются с конца (TRIM
), длина этого результата вычитаетсяиз длины самой длинной строки (-
, LENGTH
и GREATEST
), а затем используется SUBSTR
для получения результата.
Проблемы с моим подходом:
- Не работает со строками длиннее 64 бит.
- Не работает со строками, содержащими многобайтовые символы
- Очень длинные и некрасивые
- Не имеет хорошей производительности.