SQL:使用每小时滚动投票数限制来计算唯一投票数

时间:2020-03-05 18:55:41  来源:igfitidea点击:

给定一个投票表(用户投票选择,并且必须提供电子邮件地址):

votes
--
id: int
choice: int
timestamp: timestamp
ip: varchar
email: varchar

考虑到每小时只能投票两次的约束,计算"唯一"投票(用户是电子邮件+ ip的唯一组合)的最佳方法是什么?

可以计算第一次投票与最后一次投票之间的小时数,并确定该时间范围内允许的最大投票数,但是这允许用户将所有投票压缩成一个小时的窗口,然后仍然进行计数。

我意识到匿名在线投票本质上是有缺陷的,但是我不确定如何使用SQL进行此操作。我应该使用外部脚本还是其他? (对于每个选择,对于每个电子邮件+ IP对,进行投票,计算下一个+1小时时间戳,计数/丢弃/统计投票,继续进行下一小时等)

解决方案

回答

就像是

select email, ip, count(choice)
from votes
group by email, ip, datepart(hour, timestamp)

如果我理解正确

回答

我们可以重写insert语句,以仅允许基于约束插入选票:

Insert Into Votes
(Choice, Timestamp, IP, Email)
Select
Top 1
@Choice, @Timestamp, @IP, @Email
From
Votes
Where
(Select Count(*) From Votes Where
    IP = @IP
    and Email = @Email
    and Timestamp > DateAdd(h, -2, GetDate())) < 3

我们没有提到我们使用的是哪种SQL语言,所以这是在SQL Server 2005中。

回答

我认为这可以做到:

SELECT choice, count(*) 
FROM votes v 
WHERE 
  ( SELECT count(*) 
    FROM   votes v2
    WHERE  v.email = v2.email 
    AND    v.ip    = v2.ip 
    AND    v2.timestamp BETWEEN dateadd(hour, -1, v.timestamp) AND v.timestamp 
  ) < 2

仅供参考,要计算用户每小时只能投票一次的选票,我们可以这样做:

SELECT choice, count(*) 
FROM votes v 
WHERE NOT EXTISTS 
  ( SELECT * 
    FROM   votes v2
    WHERE  v.email = v2.email 
    AND    v.ip    = v2.ip 
    AND    v2.timestamp BETWEEN dateadd(h,v.timestamp,-1) AND v.timestamp 
  )