0

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

我无法理解的是如何计算每个帖子的所有赞成反对接受,然后计算每个帖子的整体声誉增益。

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

每次投票产生的声誉可以在这里看到:

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

我的目标数据库架构可以在这里找到。

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

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列无法解析:

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

4

2 回答 2

2

每个帖子的声誉比这要复杂一些。
除了赞成/反对/接受票,还有:

  1. 赏金,
  2. 代表帽,
  3. 用户的代表楼层(没有用户可以少于 1 个代表(通常))。
  4. 社区维基。
  5. 垃圾邮件或滥用标志。
  6. 根据网站的不同,对问题的赞成票数量不同。
  7. 许多帖子根本没有投票,因此 SQL 需要反映这一点。(左连接、COALESCE 等)
  8. 您是否计算帖子上已批准的建议编辑(2 分代表)?
  9. 可能是我忘记的其他东西。


根据您真正追求的目标,您可能会考虑改用此 API 方法(然后将结果按 分组post_id)。

无论如何,这是您的查询调整了一下

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
于 2019-04-10T18:57:25.840 回答
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....
于 2019-04-10T17:57:26.400 回答