为给定用户选择每个帖子的SO信誉

时间:2019-04-10 17:21:23

标签: sql sql-server-2017 dataexplorer

我目前正在对SEDE进行SQL查询,该查询从Stack Overflow中选择用户的所有帖子,并显示每个帖子所产生的信誉。

我无法确定的是如何计算每个帖子的所有赞成票赞成票接受,然后计算计算每个帖子的整体声誉收益。

所以我将按Post id分组,显示Total score,并显示总体上获得了多少声誉。

每个投票产生的声誉可以在这里查看:

+-----------+----------+--------+
| Post type | Question | Answer |
+-----------+----------+--------+
| Upvote    |    5     |   10   |
+-----------+----------+--------+
| Downvote  |    2     |    2   |
+-----------+----------+--------+
| Accept    |    5     |   15   |
+-----------+----------+--------+

我找到的数据库模式可以找到here

到目前为止,我的查询如下:

select 
  p.Id as 'Post id', 
  pt.Name as 'Post type',
  p.Score as 'Total score',
  (
    case vt.Id
      when 1 then 'Accept'
      when 2 then 'Upvote'
      else 'Downvote'
      end
  ) as 'Reputation type'
from 
  Posts p
join 
  Votes v
on
  v.PostId = p.Id
join 
  VoteTypes vt
on 
  vt.Id = v.VoteTypeId
join
  PostTypes pt
on 
  pt.Id = p.PostTypeId
where
  p.OwnerUserId = ##UserId##
and 
  vt.Id in (1, 2, 3)
order by
  p.Score,
  vt.Id
asc

它产生的输出看起来像这样:

我尝试按Vote type id分组:

group by  
  vt.id

这样我至少可以通过使用以下内容来找出每个帖子累积了多少不同的选票:

select
  ....
  count(vt.id)

但是然后我收到一个错误,指出无法解决Posts.Id列:

可以找到当前可运行但不完整的查询here(您必须输入用户ID 才能运行)

2 个答案:

答案 0 :(得分:2)

每篇文章的声誉要复杂得多。
除了“上/下/接受”票外,还有:

  1. 赏金,
  2. 代表上限
  3. 用户的代表发言权(通常每个用户的代表不得少于1个)。
  4. 社区Wiki。
  5. 垃圾邮件或滥用标志。
  6. 根据站点的不同,投票对问题的计数不同。
  7. 许多帖子根本没有投票,因此SQL需要反映出来。 (左联接,COALESCE等)
  8. 您是否在帖子中统计出建议的修改建议(代表2分)?
  9. 可能我忘记了一些其他东西。


根据您的实际需求,您可以考虑使用this API method instead(然后按post_id对结果进行分组)。

无论如何,here's your query tuned up a bit

SELECT      p.Id      AS [Post Link]
            , pt.Name AS 'Post type'
            , p.Score AS 'Total score'
            , COALESCE (vtStats.AcceptRep, 0)   AS [Accept Rep]
            , COALESCE (vtStats.numUpvotes, 0)  *  (
                CASE  p.PostTypeId
                    WHEN  1  THEN  5  -- Questions on most sites
                    WHEN  2  THEN 10  -- Answers
                    ELSE  1  -- Should not happen, but don't zero out
                END
            ) AS [Up Vt Rep]
            , COALESCE (vtStats.DwnVtRep, 0)    AS [Dwn Vt Rep]
FROM        Posts p
LEFT JOIN   (
    SELECT      v.PostId
                , SUM (CASE v.VoteTypeId    WHEN 1  THEN 15  ELSE 0  END)   AS AcceptRep
                , SUM (CASE v.VoteTypeId    WHEN 3  THEN -2  ELSE 0  END)   AS DwnVtRep
                , SUM (CASE v.VoteTypeId    WHEN 2  THEN  1  ELSE 0  END)   AS numUpvotes -- Needs special handling
    FROM        Votes v
    WHERE       v.VoteTypeId IN (1, 2, 3 )
    GROUP BY    v.PostId
)
AS vtStats  ON  vtStats.PostId = p.Id
INNER JOIN  Posttypes pt    ON pt.Id = p.PostTypeId
WHERE       p.OwnerUserId = ##UserId:Int##
ORDER  BY   p.Score DESC
            , [Accept Rep] DESC
            , pt.Name

答案 1 :(得分:0)

您可以尝试以下操作:

 select 
 p.Id as 'Post id', 
 pt.Name as 'Post type',
 SUM
 (
    case vt.Id
    when 1 then 15
    when 2 then 10
    else -2
    end
    ) as 'Total Score'
    .....
   GROUP BY P.Id, Pt.Name
   ORDER BY....