0

我已经盯着这个看了 20 分钟,无法绕开它。我以前做过,只是不记得在哪个项目中(所以我可以参考代码)。

我有一张这样的桌子:

votes [table]
  id - serial , primary
  useraccount_id - id
  object_id - id
  vote - int
  timestamp_vote - timestamp

我需要能够为任何一个对象选择当前的总票数。

但是 - 此表也可用作“时间线”视图。请注意,我使用序列作为 id 列。useraccount_id + object_id 可能有多个记录

不幸的是,这不是我需要的:

SELECT 
   vote , count(vote)
FROM 
   votes
WHERE
   object_id = 161 
GROUP BY 
   vote ;

我知道需要使用子查询和不同的,以及“按时间戳顺序排序”,以限制给定用户的最新投票。我只是不记得如何将 SELECT 串在一起。

-- 添加样本数据 --

样本数据

 id | object_id  | useraccount_id |     timestamp_created      | vote 
----+------------+----------------+----------------------------+------------
  2 |        153 |             57 | 2012-12-11 18:37:20.421013 |    1
  3 |        153 |             57 | 2012-12-11 18:48:39.963748 |    2
  4 |        153 |             57 | 2012-12-11 18:48:42.869945 |    3
  5 |        153 |             57 | 2012-12-11 18:48:48.991617 |    1
  6 |        153 |             57 | 2012-12-11 19:34:26.701351 |    2
  7 |        153 |             57 | 2012-12-11 19:35:52.449031 |    3
  8 |        153 |             57 | 2012-12-11 19:35:52.986822 |    1
  9 |        153 |             57 | 2012-12-11 19:35:53.850291 |    2
 10 |        153 |             58 | 2012-12-11 19:35:55.884202 |    3
 12 |        153 |             58 | 2012-12-11 19:35:56.803337 |    1
 13 |        153 |             59 | 2012-12-11 19:37:04.563519 |    3
 15 |        153 |             60 | 2012-12-11 19:37:40.618324 |    3
 16 |        153 |             61 | 2012-12-11 19:37:40.618324 |    3
 17 |        153 |             62 | 2012-12-11 19:37:40.618324 |    3
 18 |        153 |             63 | 2012-12-11 19:37:40.618324 |    2

预期的输出是:

vote | count
-----+------
1    | 1        # user 58 cast a vote of `3` , then `1`.  only the latest vote of `1` counted.
2    | 2        # user 57 switched votes many times. only their last vote of `2` counted. user 63 cast a vote of `2` as well.
3    | 4        # users 59,60,61,62 all voted `3`
4

2 回答 2

2
select vote, 
       count(vote) as cnt
from (
   select vote, 
          row_number() over (partition by vote order by timestamp_created desc) as rn
   from votes
)
where rn = 1
group by vote;
于 2012-12-11T19:59:20.373 回答
1

你可以尝试这样的事情:

SELECT DISTINCT ON (useraccount_id, object_id) 
       vote, 
       timestamp_vote,
       useraccount_id,
       object_id
FROM votes
WHERE object_id = 161 -- your filter here
ORDER BY useraccount_id, object_id, timestamp_vote DESC

它会给你最后一票(useraccount_id, object_id)

然后:

SELECT SUM (CASE WHEN vote THEN 1 ELSE 0 END) as true_vote_sum,
       SUM (CASE WHEN vote THEN 0 ELSE 1 END) as false_vote_sum
FROM (SELECT DISTINCT ON (useraccount_id, object_id) 
             vote
      FROM votes
      WHERE object_id = 161 -- your filter here
      ORDER BY useraccount_id, object_id, timestamp_vote DESC)

得到票数。

详细信息:DISTINCT ON , CASE WHEN

于 2012-12-11T20:05:52.540 回答