我们有2个这样的表:
1:帖子
ID Title Hits
1 Title 1 4
2 Title 2 7
3 Title 3 19
4 Title 4 8
2:点击
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
现在我们需要一个查询来检查'hits'表中是否存在具有特定PostID和IP地址的行,插入新行并增加posts.Hits一个单位(它是一个计数器)。
我们测试了这个查询:
INSERT INTO table (field) VALUES (value) ON DUPLICATE KEY UPDATE field=value
但是如您所见,IP和PostID不能是唯一键。它们可以复制给不同的用户。 如果没有PostID + IP,有没有办法在一个查询中插入和更新?
答案 0 :(得分:0)
您只需要在两个列而不是一个
列上使用唯一索引/约束create unique index unq_hits_postid_ip on hits(postid, ip);
然后您可以使用on duplicate key update
。
但是,这将适用于一个表。增加另一个表中的计数器是一个奇怪的设计。为什么不在hits
中设置计数器?如果你必须在另一个表中增加,那么你需要一个触发器。
答案 1 :(得分:0)
要为每个帖子设置唯一的ip,你会喜欢@ gordon-linoff说:
create unique index unq_hits_postid_ip on hits(postid, ip);
然后您可以使用以下语法“忽略”插入:
insert into hits (postid, ip) values (2,'5.9.9.45') on duplicate key update id=id;
然后,您可以使用触发器确保在插入IP时更新命中列:
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 ;
虽然我不会自己设计这种方式,但我根本不会记录表格中的点击次数!获取命中数是您可以在运行时使用SQL轻松完成的任务。
要计算特定帖子的点击次数(你想要posts.title的索引):
select
count(1) as hits
from posts p
join hits h on p.id = h.postid
where p.title = 'Title 2';
要获得多个帖子的点击,您可以使用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;
另外,我认为多次存储相同的IP是件好事。根据您当前的设计,您可以检查IP号访问您网站的次数:
select
ip,
count(postid) access_number
from hits
group by ip
order by access_number desc;