Выберите SO репутацию за пост для данного пользователя - PullRequest
0 голосов
/ 10 апреля 2019

В настоящее время я работаю над запросом SQL для SEDE , который выбирает все сообщения пользователя из Переполнения стека и отображает, сколько репутации генерирует каждое сообщение.

Что я не могу обернуть вокруг себя, так это как подсчитать все положительных голосов , понижающих голосов и принимает для каждого сообщения, а затем вычислять общее репутация каждого поста.

Так что я бы сгруппировал по 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 не может быть разрешен:

Текущий выполняемый, но неполный запрос можно найти здесь (для его запуска необходимо ввести идентификатор пользователя )

Ответы [ 2 ]

2 голосов
/ 10 апреля 2019

Репутация на пост немного сложнее.
Помимо голосов «за», «против», «принять», есть также:

  1. Bounties
  2. Реп шапки,
  3. Пол представителя (ни один пользователь не может иметь менее 1 представителя (обычно)).
  4. Сообщество Wiki.
  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
0 голосов
/ 10 апреля 2019

Вы можете попробовать что-то вроде этого:

 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....
...