有没有办法根据WHERE表达式计算权重加权和?

时间:2013-11-01 06:01:44

标签: sql tsql stackexchange

我想知道我的Stack Overflow声誉排除在询问和回答问题时获得或失去的所有声誉(对我而言,感觉就像“脏钱”!)

Stack Exchange的Data Explorer将允许我计算这个。但是,我只使用专有数据库和C ++包装类编程,所以我对我的SQL技能不太自信。尽管如此,我还是试了一下,最终提出了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

但这不是最好的。四个单独的查询只是为了将问题的评分加权5,将评价的评分提高10,将问题和答案的评分提高到-2?有没有办法压缩这个查询以便在一次运行中执行?

(如果您对语法,格式,良好做法等有任何辅助建议,请随时发表评论。另外,如果还有其他方法可以获得或失去特定于标签的声誉,请发表评论 - 我还没有考虑到了。)

1 个答案:

答案 0 :(得分:1)

你可以尝试像

这样的东西
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

修改

您可以使用CTE,然后使用计算中的列。

这样的东西
;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