% cat <<_EOC | psql test CRAETE TABLE rawdata ( uid INTEGER, thread_id INTEGER, voted INTEGER DEFAULT 0 ); _EOC #### % perl -nle 'printf "INSERT INTO rawdata VALUES (%d, %d, %d);\n", split' < data.txt | psql test #### % cat <<_EOSQL | psql test -- Use transactions so all temporary views are distroyed after rollback. BEGIN TRANSACTION; -- Create view with voting history per account CREATE VIEW vote_histogram AS SELECT t1.uid AS uid, t2.uid AS voted_for, sum(t1.voted) AS count FROM rawdata AS t1, rawdata AS t2 WHERE t1.thread_id = t2.thread_id AND t1.uid != t2.uid GROUP BY t1.uid, t2.uid ORDER BY t1.uid; -- Crate view with suspected accounts with votes for others greater then set threshold CREATE VIEW suspects AS SELECT uid, voted_for, count FROM vote_histogram WHERE count > $THRESHOLD; -- Build crossreferenced view of accounts who votes for each other very often SELECT s.uid AS suspect, h.uid AS voted_for, s.count AS suspect_votes, h.count AS returned_votes FROM suspects AS s, vote_histogram AS h WHERE s.voted_for = h.uid AND s.count <= h.count ORDER BY s.uid, s.count DESC; ROLLBACK; _EOSQL