MySQL Update запрос с левым соединением и группировкой по - PullRequest
44 голосов
/ 11 июня 2010

Я пытаюсь создать запрос на обновление и добиваюсь небольшого прогресса в получении правильного синтаксиса.Работает следующий запрос:

SELECT t.Index1, t.Index2, COUNT( m.EventType ) 
    FROM Table t
    LEFT JOIN MEvents m ON
        (m.Index1 = t.Index1 AND
         m.Index2 = t.Index2 AND
        (m.EventType =  'A' OR m.EventType =  'B')
    ) 
    WHERE (t.SpecialEventCount IS NULL)
    GROUP BY t.Index1, t.Index2

Создает список триплетов Index1, Index2, EventCounts.Это делается только для случая, когда t.SpecialEventCount равен NULL.Запрос на обновление, который я пытаюсь написать, должен установить для этого SpecialEventCount этого счетчика, т.е. COUNT (m.EventType) в приведенном выше запросе.Это число может быть 0 или любым положительным числом (отсюда и левое соединение).Index1 и Index2 вместе являются уникальными в таблице t и используются для идентификации событий в MEvent.

Как мне изменить запрос на выборку, чтобы он стал запросом на обновление?То есть что-то вроде

UPDATE Table SET SpecialEventCount=COUNT(m.EventType).....

, но я запутался в том, что ставить, и потерпел неудачу с многочисленными различными догадками.

Ответы [ 3 ]

79 голосов
/ 11 июня 2010

Насколько я понимаю, (Index1, Index2) - это уникальный ключ на Table, в противном случае я ожидаю, что ссылка на t.SpecialEventCount приведет к ошибке.

Отредактированный запрос для использования подзапроса, так как он не работал с использованием GROUP BY

UPDATE
    Table AS t
    LEFT JOIN (
        SELECT
            Index1,
            Index2,
            COUNT(EventType) AS NumEvents
        FROM
            MEvents
        WHERE
            EventType = 'A' OR EventType = 'B'
        GROUP BY
            Index1,
            Index2
    ) AS m ON
        m.Index1 = t.Index1 AND
        m.Index2 = t.Index2
SET
    t.SpecialEventCount = m.NumEvents
WHERE
    t.SpecialEventCount IS NULL
4 голосов
/ 30 мая 2014

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

Для обновлений попробуйте избегать объединений и использовать вместо этого коррелированные подзапросы:

UPDATE
    Table AS t
SET
    t.SpecialEventCount = (
        SELECT COUNT(m.EventType)
        FROM MEvents m
        WHERE m.EventType in ('A','B')
          AND m.Index1 = t.Index1
          AND m.Index2 = t.Index2
    )
WHERE
    t.SpecialEventCount IS NULL

Выполните профилирование, но в некоторых случаях это может быть значительно быстрее.

1 голос
/ 02 июля 2019

мой пример

update card_crowd  as cardCrowd
LEFT JOIN 
(
select cc.id , count(1) as num
from card_crowd cc LEFT JOIN 
card_crowd_r ccr on cc.id = ccr.crowd_id
group by cc.id
) as tt
on cardCrowd.id = tt.id
set cardCrowd.join_num = tt.num;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...