INSERT ... SELECT ... WHERE ... ON DUPLICATE ... mysql запрос - PullRequest
0 голосов
/ 04 февраля 2012

Пожалуйста, помогите.Я пытаюсь обновить эту таблицу с учетом текущего количества активов, которые имеют наши продукты.Если продукт уже существует в таблице, он должен обновить наиболее обновленный счетчик продукта.Однако, используя запрос ниже, MySQL возвращает мне

"ОШИБКА 1111 (HY000): недопустимое использование групповой функции".

Я не могу определить, что мойошибка или если действительно допустимо использовать счетчик в функции «на дубликат ключа»:

INSERT INTO report_count_assets
    SELECT products.product_id, 
    count(product_assets.asset_id),
    count(case when assets.asset_type_id=1 THEN 1 END), 
    count(case when assets.asset_type_id=2 THEN 1 END), 
    count(case when assets.asset_type_id=3 THEN 1 END), 
    count(case when assets.asset_type_id=11 THEN 1 END) 
    FROM products 
    LEFT JOIN product_assets USING (product_id) 
    LEFT JOIN assets USING (asset_id)
    WHERE products.brand_id=671

ON DUPLICATE KEY UPDATE
    asset_count = count(product_assets.asset_id),
    asset_type_image = count(case when assets.asset_type_id=1 THEN 1 END), 
    asset_type_video = count(case when assets.asset_type_id=2 THEN 1 END), 
    asset_type_sound = count(case when assets.asset_type_id=3 THEN 1 END), 
    asset_type_install = count(case when assets.asset_type_id=11 THEN 1 END);

Ответы [ 2 ]

4 голосов
/ 04 февраля 2012

Не думаю, что вы можете использовать агрегатные функции в ON DUPLICATE.MySQL воспринимает ваш SQL примерно так:

insert into report_count_assets
expr
on duplicate key update
...

ON DUPLICATE не знает, что происходит в expr, он знает только то, что имеет дело с одной дублирующейся строкой.Не зная, что происходит внутри expr, контекст count не может работать.Кроме того, вы должны использовать values в ОБНОВЛЕНИИ:

Вы можете использовать функцию VALUES(col_name) в предложении UPDATE для ссылки на значения столбцов из части INSERTоператор INSERT ... ON DUPLICATE KEY UPDATE.

И values(count(x)) недопустимый синтаксис.Но values(column_name) является действительным, поэтому это должно работать:

INSERT INTO report_count_assets
(product_id, asset_count, asset_type_image, asset_type_video, asset_type_sound, asset_type_install)
    SELECT products.product_id, 
    count(product_assets.asset_id),
    count(case when assets.asset_type_id=1 THEN 1 END), 
    count(case when assets.asset_type_id=2 THEN 1 END), 
    count(case when assets.asset_type_id=3 THEN 1 END), 
    count(case when assets.asset_type_id=11 THEN 1 END) 
    FROM products 
    LEFT JOIN product_assets USING (product_id) 
    LEFT JOIN assets USING (asset_id)
    WHERE products.brand_id=671
ON DUPLICATE KEY UPDATE
    asset_count = values(asset_count),
    asset_type_image = values(asset_type_image), 
    asset_type_video = values(asset_type_video), 
    asset_type_sound = values(asset_type_sound), 
    asset_type_install = values(asset_type_install);

Я должен был угадать имя столбца product_id в report_count_assets.

Если это не сработает (как видно, это не так), тогда вы можете сделать это трудным путем, предварительно вычислив SELECT.Создайте временную таблицу:

create temporary table t (
    product_id int,
    product_count int,
    assets1 int,
    assets2 int,
    assets3 int,
    assets11 int
)

Заполните ее:

INSERT INTO t (product_id, product_count, assets1, assets2, assets3, assets11)
SELECT products.product_id, 
count(product_assets.asset_id),
count(case when assets.asset_type_id=1 THEN 1 END), 
count(case when assets.asset_type_id=2 THEN 1 END), 
count(case when assets.asset_type_id=3 THEN 1 END), 
count(case when assets.asset_type_id=11 THEN 1 END) 
FROM products 
LEFT JOIN product_assets USING (product_id) 
LEFT JOIN assets USING (asset_id)
WHERE products.brand_id=671

И затем используйте эту временную таблицу для выполнения вставки, которую вы действительно хотите сделать:

insert into report_count_assets
    select product_id, product_count, assets1, assets2, assets3, assets11
    from t
on duplicate key update
    asset_count = values(product_count),
    asset_type_image = values(assets1),
    asset_type_video = values(assets2),
    asset_type_sound = values(assets3),
    asset_type_install = values(assets11)
0 голосов
/ 04 февраля 2012

Попробуйте сгруппировать по product_assets.asset_id:

.
.
WHERE products.brand_id=671
group by product_assets.asset_id
ON DUPLICATE KEY UPDATE
    asset_count = count(product_assets.asset_id)
.
.
...