RSS icon Bullet (black)
  • SQL: Обновление записи другой записью из той-же таблицы в MySQL

    Posted on Апрель 8th, 2011 CYFiVE No comments

    Исходные данные

    У нас есть таблица OUR_TABLE с колонками:

    • ID:INT;
    • COL1: VARCHAR(15);
    • COL2: VARCHAR(15);

    В ней есть две записи:

    ID COL1 COL2
    1 Колонка 1-1 Колонка 2-1
    2 Колонка 2-1 Колонка 2-2

    Наша задача заменить значение в первой строке в колонке COL2 на соответствующее значение из второй строки.

    Решение

    На вскидку нам приходит решение:

    1
    2
    3
    4
    
    UPDATE our_table
    SET
       col2 = (SELECT col2 FROM our_table WHERE id = 2)
    WHERE id = 1

    Но не тут-то было! MySQL выдаст вам ошибку, которую можно интерпретировать очень просто, во вложенном подзапросе не может фигурировать обновляемая таблица. Возникает вопрос, как нам быть? Ведь хочется все сделать красиво… Курение документации по MySQL подсказало решение: в синтаксисе UPDATE можно использовать соединения (JOIN), и вот оно готовое рабочее решение:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    
    UPDATE our_table ot
    LEFT JOIN (
       SELECT
           1 AS id, otj.col2
       FROM our_table otj
       WHERE otj.id = 2
    ) ou ON ou.id = ot.id
    SET
        ot.col2 = ou.col2
    WHERE ot.id = 2

    Практическое применение

    Как это использовать на практике? Просто, вот пример как в phpBB скопировать одну запись на место другой:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    
    $sql = "UPDATE ".POSTS_TEXT_TABLE." ptt1
           LEFT JOIN (
                SELECT
                  ".$new_topic['topic_first_post_id']." post_id,
    	      ptt.bbcode_uid, ptt.post_subject, ptt.post_text
                FROM ".POSTS_TEXT_TABLE." ptt
                WHERE ptt.post_id = ".$topic['topic_first_post_id']."
           ) ptt2 ON ptt1.post_id = ptt2.post_id
           SET ptt1.bbcode_uid = ptt2.bbcode_uid,
               ptt1.post_subject = ptt2.post_subject,
               ptt1.post_text = ptt2.post_text
           WHERE ptt1.post_id = ".$new_topic['topic_first_post_id'];

    Заключение

    К чему такие сложности? Производительность складывается из мелочей, и одной из них является то, что мы лишний раз не передаем данные на клиента (как было сказано в одной из предыдущих моих записей) передача данных на клиента после выполнения запроса самая узкая часть в производительности.

    SQL

    Leave a reply