2017-04-10 2 views
0

Nous avons 2 tables comme celles-ci:vérifier MySQL si la ligne est existe pas, puis insérez (sans clé unique)

1: messages

ID Title Hits 
1 Title 1 4 
2 Title 2 7 
3 Title 3 19 
4 Title 4 8 

2: hits

ID PostID  IP 
1  2  5.9.9.45 
2  3  5.9.9.45 
3  2  72.5.4.9 
4  4  5.9.9.45 

maintenant nous avons besoin d'une requête qui vérifie si une ligne avec un PostID ET une adresse IP spécifique n'existe pas dans la table 'hits', insère une nouvelle ligne et augmente le nombre de posts.Hits une unité (C'est un compteur).

Nous avons testé cette requête:

INSERT INTO table (field) VALUES (value) ON DUPLICATE KEY UPDATE field=value 

Mais comme vous le voyez, IP et PostID ne peut pas être clé unique. Ils peuvent dupliquer pour différents utilisateurs. Y at-il un moyen d'insérer et de mettre à jour dans une requête s'il n'y a pas PostID + IP?

Répondre

0

Pour avoir les IP uniques par poste que vous faites comme @ gordon-Linoff dit:

create unique index unq_hits_postid_ip on hits(postid, ip); 

Ensuite, vous pouvez utiliser la syntaxe suivante pour "ignorer" l'insert:

insert into hits (postid, ip) values (2,'5.9.9.45') on duplicate key update id=id; 

Vous pouvez ensuite utiliser un déclencheur pour vous assurer que la colonne hits est mis à jour lorsque ip est inséré:

DELIMITER/

CREATE TRIGGER trg_ai_hits AFTER INSERT ON hits 
    FOR EACH ROW 
BEGIN 
    UPDATE posts SET hits = hits + 1 WHERE id = NEW.postid; 
END; 
/

DELIMITER ; 

Bien que je ne Je ne ferais pas moi-même le compte du nombre de hits dans une table! Obtenir le nombre de hits est plutôt quelque chose que vous pouvez faire facilement à l'exécution avec SQL.

Pour compter le nombre de visites sur un poste spécifique (vous voulez un index sur posts.title ici):

select 
count(1) as hits 
from posts p 
join hits h on p.id = h.postid 
where p.title = 'Title 2'; 

Pour obtenir plusieurs résultats pour les messages que vous pouvez utiliser une clause GROUP BY:

select 
p.title, 
count(1) as hits 
from posts p 
join hits h on p.id = h.postid 
where p.title in ('Title 2', 'Title 3') 
group by p.title 
order by hits desc; 

En outre, je pense qu'il est bon que vous stockiez la même adresse IP plusieurs fois. Avec votre conception actuelle, vous pouvez par exemple vérifier combien de fois un numéro IP a accédé à votre site:

select 
ip, 
count(postid) access_number 
from hits 
group by ip 
order by access_number desc; 
+0

Le défi est le suivant: 1- Lorsqu'un utilisateur ouvre une page de publication, augmentez ce nombre de publications. 2- Si cet utilisateur ouvre un autre message, son hit augmente. 3- Si cet utilisateur ouvre une publication pour la deuxième fois, ne pas le faire! –

+0

Ensuite, vous créez un index unique sur les hits comme @ gordon-linoff dit. –

+0

Mise à jour de ma réponse avec un exemple d'insertion. –

0

Vous juste besoin d'un index unique/contrainte sur deux colonnes plutôt que:

create unique index unq_hits_postid_ip on hits(postid, ip); 

vous pouvez utiliser on duplicate key update.

Toutefois, cela fonctionnera sur une table. Incrémenter un compteur dans une autre table est un design curieux. Pourquoi ne pas simplement avoir le compteur en hits? Si vous devez incrémenter dans une autre table, vous aurez besoin d'un déclencheur.

+0

Non! Nous voulons que si des doublons se produisent, ne faites rien! Mais s'il s'agit d'une nouvelle ligne, insérez-la et mettez à jour une autre colonne de la table. –