2012-02-04 1 views
0

Aidez-nous s'il vous plaît. J'essaie de mettre à jour ce tableau avec le nombre actuel d'actifs de nos produits. Si le produit existe déjà dans la table, il doit mettre à jour le nombre le plus mis à jour du produit. Cependant, en utilisant la requête ci-dessous, mysql me retourneINSERT ... SELECT ... OERE ... SUR DUPLICATE ... requête mysql

"ERREUR 1111 (HY000): Utilisation invalide de la fonction de groupe".

Je ne peux pas déterminer ce qui est mon erreur ou si elle est vraiment valide pour utiliser count en fonction « clé en double »:

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); 
+0

thi s [Question] (http://stackoverflow.com/questions/2330840/mysql-invalid-use-of-group-function) peut vous aider – diEcho

+0

Salut @diEcho, je ne suis pas particulièrement à la recherche de quels produits ont ces chiffres certains dans leurs actifs. Ma préoccupation est la partie mise à jour de la requête lorsque le produit est déjà présent dans la table. Je ne sais pas comment la requête select-join peut être implémentée sur 'ON DUPLICATE KEY UPDATE' –

Répondre

4

Je ne pense pas que vous pouvez utiliser des fonctions d'agrégation dans la ON DUPLICATE. MySQL voit SQL un peu comme ceci:

insert into report_count_assets 
expr 
on duplicate key update 
... 

Le Duplicate ne sait pas ce qui se passe dans expr, il sait seulement qu'il a une seule rangée de double à traiter. Sans savoir ce qui se passe à l'intérieur expr, il n'y a pas de contexte pour que les count fonctionnent. En outre, vous êtes censé utiliser values dans la MISE À JOUR:

Vous pouvez utiliser la fonction VALUES(col_name) dans la clause UPDATE de se référer à des valeurs de colonne de la partie INSERT de la déclaration INSERT ... ON DUPLICATE KEY UPDATE.

Et values(count(x)) n'est pas une syntaxe valide. Mais values(column_name) est valable si cela devrait fonctionner:

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); 

je devais deviner le nom de la colonne product_id dans report_count_assets.

Si cela ne fonctionne pas (comme apparemment pas), alors vous pouvez le faire à la dure en précomputing le SELECT. Créer une table temporaire:

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

que vous le remplissiez:

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 

Et puis utilisez cette table temporaire pour faire l'insert que vous voulez vraiment faire:

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

Bonjour @mu est trop court, merci beaucoup! Tu as sauvé beaucoup de sang de moi. –

+0

@ Jan-DeanFajardo: J'ai une meilleure solution ce matin si ça vous intéresse. –

+0

oui s'il vous plaît, j'aimerais savoir. –

0

Essayez de groupe par 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) 
. 
. 
+0

Voir également ce [lien] (http://stackoverflow.com/questions/1712240/mysql-insert-into-on-duplicate-key -with-select-statement-issue) –