Question

I wanted to know my Stack Overflow reputation excluding all the reputation gained or lost from asking and answering questions(—it feels like "dirty money" to me!)

Stack Exchange's Data Explorer would allow me to calculate this. But, I'd only ever programmed using proprietary databases and C++ wrapper classes, so I wasn't too confident about my SQL skills. Nonetheless, I gave it a shot, and eventually came up with a query that provided my answer:

-- (approximate) reputation gained/lost on a specified tag
-- only counts post upvotes and downvotes

DECLARE @UserId        int = ##UserId##
DECLARE @QuestionsUp   int = 0;
DECLARE @QuestionsDown int = 0;
DECLARE @AnswersUp     int = 0;
DECLARE @AnswersDown   int = 0;
DECLARE @Tag           nvarchar(25) = 'regex';

SELECT
    @QuestionsUp = COUNT(*)
FROM Tags
    INNER JOIN PostTags ON PostTags.TagId = Tags.id
    INNER JOIN Posts ON Posts.ParentId = PostTags.PostId
    INNER JOIN Votes ON Votes.PostId = Posts.Id and VoteTypeId = 2
WHERE 
    Posts.OwnerUserId = @UserId and
    Posts.PostTypeId = 1 and
    Tags.TagName = @Tag

SELECT
    @QuestionsDown = COUNT(*)
FROM Tags
    INNER JOIN PostTags ON PostTags.TagId = Tags.id
    INNER JOIN Posts ON Posts.ParentId = PostTags.PostId
    INNER JOIN Votes ON Votes.PostId = Posts.Id and VoteTypeId = 3
WHERE 
    Posts.OwnerUserId = @UserId and
    Posts.PostTypeId = 1 and
    Tags.TagName = @Tag

SELECT
    @AnswersUp = COUNT(*)
FROM Tags
    INNER JOIN PostTags ON PostTags.TagId = Tags.id
    INNER JOIN Posts ON Posts.ParentId = PostTags.PostId
    INNER JOIN Votes ON Votes.PostId = Posts.Id and VoteTypeId = 2
WHERE 
    Posts.OwnerUserId = @UserId and
    Posts.PostTypeId = 2 and
    Tags.TagName = @Tag

SELECT
    @AnswersDown = COUNT(*)
FROM Tags
    INNER JOIN PostTags ON PostTags.TagId = Tags.id
    INNER JOIN Posts ON Posts.ParentId = PostTags.PostId
    INNER JOIN Votes ON Votes.PostId = Posts.Id and VoteTypeId = 3
WHERE 
    Posts.OwnerUserId = @UserId and
    Posts.PostTypeId = 2 and
    Tags.TagName = @Tag
    
SELECT @QuestionsUp * 5 +
       @AnswersUp * 10 +
       (@QuestionsDown + @AnswersDown) * -2

This can't be the best one can do, though. Four separate queries just to weight upvoted questions by 5, upvoted answers by 10, and downvoted questions and answers by -2? Is there a way to compact this query to execute in a single run?

(Please feel free to comment if you have any auxiliary advice regarding syntax, formatting, good practices, and such. Also, please do comment if there are other ways to gain or lose reputation—specific to tags—that I haven't factored in.)

No correct solution

OTHER TIPS

You could always try something like

SELECT
    SUM(
        CASE
            WHEN VoteTypeId = 2 AND Posts.PostTypeId = 1
                THEN 1
            ELSE 0
        END
    )   QuestionsUp,
    SUM(
        CASE
            WHEN VoteTypeId = 3 AND Posts.PostTypeId = 1
                THEN 1
            ELSE 0
        END
    )   QuestionsDown,
    SUM(
        CASE
            WHEN VoteTypeId = 2 AND Posts.PostTypeId = 2
                THEN 1
            ELSE 0
        END
    )   AnswersUp,
    SUM(
        CASE
            WHEN VoteTypeId = 3 AND Posts.PostTypeId = 2
                THEN 1
            ELSE 0
        END
    )   AnswersDown
FROM Tags
    INNER JOIN PostTags ON PostTags.TagId = Tags.id
    INNER JOIN Posts ON Posts.ParentId = PostTags.PostId
    INNER JOIN Votes ON Votes.PostId = Posts.Id 
WHERE 
    Posts.OwnerUserId = @UserId and
    Tags.TagName = @Tag

EDIT:

You could use a CTE and then used the columns in your calcs.

Something like

;WITH Vals AS (
        SELECT
            SUM(
                CASE
                    WHEN VoteTypeId = 2 AND Posts.PostTypeId = 1
                        THEN 1
                    ELSE 0
                END
            )   QuestionsUp,
            SUM(
                CASE
                    WHEN VoteTypeId = 3 AND Posts.PostTypeId = 1
                        THEN 1
                    ELSE 0
                END
            )   QuestionsDown,
            SUM(
                CASE
                    WHEN VoteTypeId = 2 AND Posts.PostTypeId = 2
                        THEN 1
                    ELSE 0
                END
            )   AnswersUp,
            SUM(
                CASE
                    WHEN VoteTypeId = 3 AND Posts.PostTypeId = 2
                        THEN 1
                    ELSE 0
                END
            )   AnswersDown
        FROM Tags
            INNER JOIN PostTags ON PostTags.TagId = Tags.id
            INNER JOIN Posts ON Posts.ParentId = PostTags.PostId
            INNER JOIN Votes ON Votes.PostId = Posts.Id 
        WHERE 
            Posts.OwnerUserId = @UserId and
            Tags.TagName = @Tag
        )
SELECT  QuestionsUp * 5 +
       AnswersUp * 10 +
       (QuestionsDown + AnswersDown) * -2
FROM    Vals
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top