[mysql] Limiter un INSERT INTO suivant le nombre d'occurence

Phil.Antrope
Invité n'ayant pas de compte PHPfrance

16 août 2007, 14:36

Bonjour à tous,

Ca fait un petit temps déjà que je me pose cette question :
Est-ce que c'est possible, en une seule requêter, de conditionner un INSERT afin qu'il
n'ajoute certaines valeur à la condition qu'un certain nombre d'occurence ne soit pas dépassé ?

Je m'explique : j'ai par exemple une table avec 2 champs pour faire simple : user_id et user_favori, et j'aimerai, en une seule requete, ajouter mes valeurs, par exemple "user0001" et "favori0001" a co0dnition que l'utilisateur n'ai pas déjà plus de 5 favoris.

Autrement dit, si la table contient déjà 5 champs avec le même user_id, on ajoute pas d'autres valeurs, mais si la table n'en contient que 1,2,3 ou 4 alors on ajoute les valeurs "user0001" et "favori0001".

Quelqu'un a une petite idée de comment je pourrai réaliser ça en une seule requête, si c'est possible ?

d0m
Mammouth du PHP | 1141 Messages

16 août 2007, 14:46

je me lance mais c'est à tester je n'en suis pas sur du tout :

Code : Tout sélectionner

INSERT INTO table (user_id,user_favori) VALUES (user0001 et favori0001) WHERE 5>(SELECT COUNT(*) FROM table WHERE user_id=user0001)

Avatar du membre
Administrateur PHPfrance
Administrateur PHPfrance | 13231 Messages

16 août 2007, 14:56

Ce n'est qu'une remarque en passant, mais cette méthode ne te permet pas de détecter pourquoi l'insertion ne s'est pas faite ... :?

Si tu détectes qu'aucune ligne n'a été insérée, comment sais-tu s'il s'agit que le membre dispose déjà de 5 lignes ou s'il s'agit d'une autre erreur ?

Personnellement, je serais passé par un SELECT puis un INSERT
Connaître son ignorance est la meilleure part de la connaissance
Pour un code lisible : n'hésitez pas à sauter des lignes et indenter

twitter - site perso - Github - Zend Certified Engineer

ViPHP
ViPHP | 5924 Messages

16 août 2007, 15:03

Qu'appelles tu une erreur zeus ?
Parce qu'en cas d'erreur ( SQL ), il aura un affected_rows() de -1.

Avatar du membre
Administrateur PHPfrance
Administrateur PHPfrance | 13231 Messages

16 août 2007, 15:05

Effectivement, le mot est extremement mal choisi. :-/

Je pensais plutôt à un cas de figure où mysql_affected_rows() retournerais 0 :?
Connaître son ignorance est la meilleure part de la connaissance
Pour un code lisible : n'hésitez pas à sauter des lignes et indenter

twitter - site perso - Github - Zend Certified Engineer

Phil.Antrope
Invité n'ayant pas de compte PHPfrance

16 août 2007, 16:54

Merci pour vos réponses,

En fait ma question était plus théorique qu'autre chose, la méthode que j'utilise actuellement implique bien un SELECT avant l'INSERT, je me posais juste la question de savoir si c'était possible, mais je n'avais effectivement pas pensé au rapport d'erreur éventuel.

ViPHP
ViPHP | 5924 Messages

16 août 2007, 16:56

Je pensais plutôt à un cas de figure où mysql_affected_rows() retournerais 0 :?
Ouais mais je ne vois pas trop dans quels cas critiques il pourrait avoir un affected_rows à 0 mis à part bien sur s'il y a trop de favoris.

@Phil.Antrope : Tiens, d'ailleurs, c'est pour un seul utilisateur ou bien pour tous que tu veux le faire ?

Phil.Antrope
Invité n'ayant pas de compte PHPfrance

16 août 2007, 17:14

Potentiellement c'est pour tous les utilisateurs (genre 10 000).
Chaque utilisateur pouvant avoir jusqu'a 5 favoris maximum.

ViPHP
ViPHP | 5924 Messages

16 août 2007, 17:43

Bah si tu veux faire tout en même temps, c'est :

Code : Tout sélectionner

INSERT INTO table (user_id,user_favori) SELECT user_id, favori0001 FROM table GROUP BY user_id HAVING COUNT(user_id)>5
Au passage, ca marche aussi pour un seul utilisateur :

Code : Tout sélectionner

INSERT INTO table (user_id,user_favori) SELECT user_id, favori0001 FROM table WHERE user_id=user0001 GROUP BY user_id HAVING COUNT(user_id)>5

Phil.Antrope
Invité n'ayant pas de compte PHPfrance

16 août 2007, 18:26

Quand j'essaie

Code : Tout sélectionner

INSERT INTO user_fav( user_id, serie_id, team_id ) SELECT user_id, favori0001 FROM user_fav WHERE user_id = user0001 GROUP BY user_id HAVING COUNT( user_id ) >5
Mysql me répond :

#1054 - Unknown column 'favori0001' in 'field list'

Comment y mettre des valeurs sont forcément faire référence à une table existante ?

ViPHP
ViPHP | 5924 Messages

16 août 2007, 18:30

Mets des quotes à tes valeurs.

Phil.Antrope
Invité n'ayant pas de compte PHPfrance

16 août 2007, 18:53

Effectivement, du coup ça marche mieux :lol:

Merci :wink:

Avatar du membre
Administrateur PHPfrance
Administrateur PHPfrance | 13231 Messages

16 août 2007, 19:41

Modération :
Puisque ta question est résolue, j'ajoute le tag [Résolu]
pour indiquer aux personnes qui voudront consulter ce sujet qu'il contient une solution.

Tu peux réaliser cette opération toi-même
en cliquant sur le bouton Image qui s'affiche en haut à gauche de ce sujet
si tu as posté le 1er message en tant que membre (inscrit et identifié).

Alors... inscris-toi !!! ;)
Connaître son ignorance est la meilleure part de la connaissance
Pour un code lisible : n'hésitez pas à sauter des lignes et indenter

twitter - site perso - Github - Zend Certified Engineer

Phil.Antrope
Invité n'ayant pas de compte PHPfrance

16 août 2007, 23:42

Tant que j'y suis, je peux me permettre encore une petite question ?

Comment je fais la même chose mais en limitant l'ajout des valeurs avec 2 conditions ?

J'ai, par exemple, 3 champs : user_id, serie_id, team_id

et je voudrais limiter le nombre global de favoris d'un user précis à 5 serie_id différent,
chaque serie_id pouvant avoir 5 team_id différent chacun...

Je sais pas si je suis assez clair. En gros ça me donnerait, par exemple dans la table :

user_id = 5, serie_id = 10, team_id = 12
user_id = 5, serie_id = 10, team_id = 62
user_id = 5, serie_id = 10, team_id = 78
user_id = 5, serie_id = 10, team_id = 64
user_id = 5, serie_id = 25, team_id = 15
user_id = 5, serie_id = 25, team_id = 99

Donc en tout globalement le user disposerait de 25 row maximum (5 series x 5 team chacunes)
Bêtement dans mon élan de brute j'avais mis ceci :

Code : Tout sélectionner

INSERT INTO user_fav (user_id,serie_id,team_id) SELECT "IDUSER", "IDSERIE", "IDTEAM" FROM user_fav WHERE (user_id="IDUSER" GROUP BY user_id HAVING COUNT(user_id)<5) AND (user_id="IDUSER" GROUP BY serie_id HAVING COUNT(serie_id)<5)
Mais bon, bien sur ça marche pas :lol:

ViPHP
ViPHP | 5924 Messages

17 août 2007, 00:58

Bah non, tu fais pareil que tout à l'heure, mais avec 25 au lieu de 5…