Хорошо, у меня есть SQL-запрос, который я пытаюсь сгенерировать, который объединит записи на основе некоторой логики. В конечном итоге мне нужно это для каскадирования, но я сталкиваюсь с некоторыми проблемами, связанными с объединением вещей больше, чем я хочу.
Посмотрим, смогу ли я проиллюстрировать. У меня есть таблица:
CREATE TABLE IF NOT EXISTS doc_lines (
id bigint(20) NOT NULL AUTO_INCREMENT,
file_id bigint(20) NOT NULL,
line int(4) NOT NULL,
end_line int(4) NOT NULL,
type
VARCHAR(100),
text
VARCHAR( 5120 ) NOT NULL,
PRIMARY KEY (id),
UNIQUE KEY file_id (file_id,line);
INSERT INTO doc_lines VALUES(1,1,1,1,NULL, 'abcdefg');
INSERT INTO doc_lines VALUES(1,1,2,2,NULL, 'hijkl');
INSERT INTO doc_lines VALUES(1,1,3,3,NULL, 'mn');
INSERT INTO doc_lines VALUES(1,1,4,4,NULL, 'op');
INSERT INTO doc_lines VALUES(1,1,5,5,NULL, 'qrs');
INSERT INTO doc_lines VALUES(1,1,6,6,NULL, 'tuv.');
INSERT INTO doc_lines VALUES(1,1,7,7,NULL, 'wxy');
INSERT INTO doc_lines VALUES(1,1,8,8,NULL, 'zab');
Я пытаюсь объединить значения «текст», когда две строки в строке соответствуют определенному условию.
например. Мой существующий запрос выглядит примерно так:
UPDATE doc_lines AS a
JOIN doc_lines AS b ON a.file_id = b.file_id AND a.end_line + 1 = b.line
SET a.end_line
= b.end_line
, b.type
="DELETE", a.text
=CONCAT(a.text
, " ", TRIM(b.text
))
WHERE b.text
REGEXP '^[a-z]$';
Затем я проверяю это:
DELETE from doc_lines WHERE 'type'="DELETE";
Проблема, с которой я столкнулся, заключается в том, что строка 1 соответствует строке 2, что обозначает строку 2 для удаления ....
Строка 2 соответствует строке 3, которая помечает строку 3 для удаления ...
Строка 3 соответствует строке 4, которая помечает строку 4, для удаления ...
и т.д.
В результате я удаляю больше строк, чем хочу.
Сначала я подумал, что смогу сделать это, чтобы пропустить все остальные строки:
UPDATE doc_lines AS a
JOIN doc_lines AS b ON a.file_id = b.file_id AND a.end_line + 1 = b.line
SET a.end_line
= b.end_line
, b.type
="DELETE", a.text
=CONCAT(a.text
, " ", TRIM(b.text
))
WHERE b.text
REGEXP '^[a-z]$' AND a.type
<> "DELETE";
Но обновление одной записи в запросе, кажется, не вступает в силу до тех пор, пока запрос не будет выполнен, в результате вышеприведенный результат не будет вести себя по-другому ...
В результате я подумал: «Ну, почему бы не обработать все нечетные строки, а затем все четные?», Поэтому я соответствующим образом обновил свой запрос:
UPDATE doc_lines AS a
JOIN doc_lines AS b ON a.file_id = b.file_id AND a.end_line + 1 = b.line
SET a.end_line
= b.end_line
, b.type
="DELETE", a.text
=CONCAT(a.text
, " ", TRIM(b.text
))
WHERE b.text
REGEXP '^[a-z]$' AND a.line
% 2=0;
Проблема в том, что мне нужно выполнить запрос более одного раза, потому что в конечном итоге я хочу, чтобы строки 1-6 были объединены и 7-8 (на моем примере). Каждый последующий вызов объединяет строки со строкой после нее, когда он совпадает.
Проблема в том, что в конечном итоге я попадаю в ту же ситуацию, что и в моем исходном запросе, и я отмечаю некоторую строку для удаления, которая также использовалась для пометки других строк для удаления.
Даже если я в конечном итоге поворачиваюсь нечетно и четно на линиях, или на id, или на end_line, в какой-то момент получается совпадение.
Есть идеи? Есть ли способ обработки любой другой записи в базе данных, не основанной на ее фактическом значении?