在评级系统中寻找互惠票的方法
Methods to find reciprocating votes in rating system
我有一个主动投票系统,它本质上归结为一个数据库 table,包含列 "votefrom" 和 "voteto"。
基本上,我正在尝试开发一个可以检测滥用行为的警报系统。如果找到一种方法来检测互惠投票(倾向于主要为彼此投票的人),或者可能是此类投票的集群,就是这样一种情况。
理想的结果是一个用户列表,其中每个用户旁边都有一个匹配的用户和一个百分比,表明例如用户 A 将 10% 的选票投给了用户 B。这显然在降序排列,因此最倾向于专门为另一位用户投票的用户排在最前面。
所以,我的问题是,仅在查询中这是否可行,或者 SQL 能带我走多远?
任何指向现有实现的指针? (最好是PHP)
仅作为示例(使用 MS SQL 服务器)但适用于支持 COUNT() OVER()[=14 的任何 SQL 变体=]
CREATE TABLE mytable(
votefrom INTEGER
,voteto INTEGER
);
INSERT INTO mytable(votefrom,voteto) VALUES (100,200);
INSERT INTO mytable(votefrom,voteto) VALUES (100,200);
INSERT INTO mytable(votefrom,voteto) VALUES (100,200);
INSERT INTO mytable(votefrom,voteto) VALUES (100,200);
INSERT INTO mytable(votefrom,voteto) VALUES (100,200);
INSERT INTO mytable(votefrom,voteto) VALUES (100,300);
INSERT INTO mytable(votefrom,voteto) VALUES (100,400);
INSERT INTO mytable(votefrom,voteto) VALUES (100,500);
INSERT INTO mytable(votefrom,voteto) VALUES (100,600);
INSERT INTO mytable(votefrom,voteto) VALUES (100,700);
查询:
select distinct
votefrom
, voteto
, count(*) over(partition by votefrom, voteto) fromto
, count(*) over(partition by votefrom) fromtot
, count(*) over(partition by votefrom, voteto) * 100 / count(*) over(partition by votefrom) pct
from mytable
结果:
+----+----------+--------+--------+---------+-----+
| | votefrom | voteto | fromto | fromtot | pct |
+----+----------+--------+--------+---------+-----+
| 1 | 100 | 200 | 5 | 10 | 50 |
| 2 | 100 | 300 | 1 | 10 | 10 |
| 3 | 100 | 400 | 1 | 10 | 10 |
| 4 | 100 | 500 | 1 | 10 | 10 |
| 5 | 100 | 600 | 1 | 10 | 10 |
| 6 | 100 | 700 | 1 | 10 | 10 |
+----+----------+--------+--------+---------+-----+
参见:http://rextester.com/UESP57757
MySQL 中的语法会完全不同,而 dbms 不支持 COUNT() OVER()
我有一个主动投票系统,它本质上归结为一个数据库 table,包含列 "votefrom" 和 "voteto"。
基本上,我正在尝试开发一个可以检测滥用行为的警报系统。如果找到一种方法来检测互惠投票(倾向于主要为彼此投票的人),或者可能是此类投票的集群,就是这样一种情况。
理想的结果是一个用户列表,其中每个用户旁边都有一个匹配的用户和一个百分比,表明例如用户 A 将 10% 的选票投给了用户 B。这显然在降序排列,因此最倾向于专门为另一位用户投票的用户排在最前面。
所以,我的问题是,仅在查询中这是否可行,或者 SQL 能带我走多远?
任何指向现有实现的指针? (最好是PHP)
仅作为示例(使用 MS SQL 服务器)但适用于支持 COUNT() OVER()[=14 的任何 SQL 变体=]
CREATE TABLE mytable(
votefrom INTEGER
,voteto INTEGER
);
INSERT INTO mytable(votefrom,voteto) VALUES (100,200);
INSERT INTO mytable(votefrom,voteto) VALUES (100,200);
INSERT INTO mytable(votefrom,voteto) VALUES (100,200);
INSERT INTO mytable(votefrom,voteto) VALUES (100,200);
INSERT INTO mytable(votefrom,voteto) VALUES (100,200);
INSERT INTO mytable(votefrom,voteto) VALUES (100,300);
INSERT INTO mytable(votefrom,voteto) VALUES (100,400);
INSERT INTO mytable(votefrom,voteto) VALUES (100,500);
INSERT INTO mytable(votefrom,voteto) VALUES (100,600);
INSERT INTO mytable(votefrom,voteto) VALUES (100,700);
查询:
select distinct
votefrom
, voteto
, count(*) over(partition by votefrom, voteto) fromto
, count(*) over(partition by votefrom) fromtot
, count(*) over(partition by votefrom, voteto) * 100 / count(*) over(partition by votefrom) pct
from mytable
结果:
+----+----------+--------+--------+---------+-----+
| | votefrom | voteto | fromto | fromtot | pct |
+----+----------+--------+--------+---------+-----+
| 1 | 100 | 200 | 5 | 10 | 50 |
| 2 | 100 | 300 | 1 | 10 | 10 |
| 3 | 100 | 400 | 1 | 10 | 10 |
| 4 | 100 | 500 | 1 | 10 | 10 |
| 5 | 100 | 600 | 1 | 10 | 10 |
| 6 | 100 | 700 | 1 | 10 | 10 |
+----+----------+--------+--------+---------+-----+
参见:http://rextester.com/UESP57757
MySQL 中的语法会完全不同,而 dbms 不支持 COUNT() OVER()