MySql - SQL - Как избежать повторяющихся обновлений в одном запросе - PullRequest
0 голосов
/ 25 ноября 2011

Хорошо, у меня есть 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, в какой-то момент получается совпадение.

Есть идеи? Есть ли способ обработки любой другой записи в базе данных, не основанной на ее фактическом значении?

1 Ответ

0 голосов
/ 25 ноября 2011

хорошо, я понял что-то, что работает.

Если у кого-то есть что-то лучше или эффективнее ... пожалуйста, дайте мне знать.

Мое решение состояло в том, чтобы создать временную таблицу, которую я присоединяю к таблице a:

CREATE TABLE update_index SELECT id, @row := @row + 1 as row FROM doc_lines, (SELECT @row := 0) AS r;

Затем я могу присоединиться к этой таблице, чередовать четные, затем удалять, затем нечетные, затем удалять, затем заново создавать временную таблицу и повторять.

Много шагов, но это работает.

Меня определенно заинтересует более элегантный или эффективный метод!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...