【问题标题】:Get TOP 8 PERCENT then insert into another table获取 TOP 8 PERCENT 然后插入另一个表
【发布时间】:2016-04-05 13:35:13
【问题描述】:

我有一个场景,我需要根据 3 个类别的 5 位不同评委确定的每个艺术家/唱片的分数来计算前 8% 的唱片。

为此,我在存储过程中使用以下内容

SELECT TOP 8 PERCENT 
    *
FROM
    (SELECT 
         MEM.Id,
         EN.artistName, EN.dateAdded, EN.voteStatus, 
         ES.enterNextRound, ES.notified, ES.voted,
         GR.genre,
         ES.entrantId AS bandID,
         ES.rnd2Feedback AS feedback, ES.compositionVote,
         ES.vocalsVote, ES.originalityVote,
         (SELECT COUNT(Voted)
          FROM recEntrantStatus
          WHERE voted = 1
            AND roundId = 2
            AND entrantId = ES.entrantId) CountVoted,
         (SELECT (COUNT(Voted)/*-1*/)
          FROM recEntrantStatus
          WHERE roundId = 2
            AND entrantId = ES.entrantId) CountTotalVotes,
         (SELECT COUNT(Id)
          FROM recMembers) TotalJudges,
         (SELECT coalesce(SUM(compositionVote),0)
          FROM recEntrantStatus
          WHERE roundId = 2
            AND entrantId = ES.entrantId
            AND voted = 1) SumTotalComposition,
         (SELECT coalesce(SUM(vocalsVote),0)
          FROM recEntrantStatus
          WHERE roundId = 2
            AND entrantId = ES.entrantId
            AND voted = 1) SumTotalVocals,
         (SELECT coalesce(SUM(originalityVote),0)
          FROM recEntrantStatus
          WHERE roundId = 2
            AND entrantId = ES.entrantId
            AND voted = 1) SumTotalOrig,
         (SELECT SUM(compositionVote + vocalsVote + originalityVote)
          FROM recEntrantStatus
          WHERE roundId = 2
            AND entrantId = ES.entrantId) TotalVoteScore
     FROM 
         recMembers AS MEM
     LEFT JOIN 
         recEntrantStatus AS ES ON MEM.Id = ES.judgeId
     LEFT JOIN 
         recEntrants AS EN ON ES.entrantId = EN.Id
     LEFT JOIN 
         recGenre AS GR ON EN.genreId = GR.Id
     WHERE 
         MEM.Id = 4
         AND ES.roundId = @input) q
ORDER BY 
    TotalVoteScore DESC, compositionVote DESC, 
    originalityVote DESC, vocalsVote DESC

现在,为了准备下一轮的比赛,我需要获取这个结果集并为每一行创造一个新记录,为所有评委(目前总共大约 20 人)各创造一次。因此,对于这个前 8% 的记录集(大约 12 个参赛者/记录),这将是 20 条记录。因此,这应该会导致插入大约 12*20 条记录。

在前几轮比赛中,我只是选择了“所有”参赛者,他们有一个位字段用作标记,表示他们将进入下一轮。我用以下代码做到了这一点:

INSERT INTO recEntrantStatus (entrantId, roundId, judgeId, notified, voted, enterNextRound)
    SELECT 
        r.entrantId, (@input + 1), j.judgeId /*Now getting tblJudges Id*/, 0, 0, 0
    FROM 
        recEntrantStatus r
    -- Get all of the judges
    CROSS JOIN 
        (SELECT DISTINCT Id AS judgeId 
         FROM recMembers 
         WHERE Privilege >= 2) AS j
    WHERE 
        r.roundId = @input
        AND r.voted = 1
        AND r.enterNextround = 1

所以,我的问题本质上是如何结合这两个查询,以便从当前轮次中获得前 8%,然后为这前 8% 的参赛者中的每一个添加一个新的记录,然后为 20 名评委中的每一个添加一个新记录?

不幸的是,用检索 TOP 8% 的方法替换 CROSS JOIN SELECT 并不是一个简单的案例。

有什么建议吗??

【问题讨论】:

    标签: sql-server tsql select stored-procedures sql-insert


    【解决方案1】:

    使用可识别您的 TOP 8 PERCENT 成员和所有评委的 CTE 编写查询,然后将两者交叉连接,以便插入多条记录。

    这是查询的框架,您可以在其中填写所有属性和必要条件。

    WITH Members AS
    (
        --note, for a CTE, all columns in the select must have a name (or you must specify the column names above next to the CTE name)
        SELECT TOP 8 PERCENT mem.id, entrantId, ... FROM recMembers [mem] ... ORDER BY ...
    ),
    Judges AS
    (
        SELECT Id [judgeId] FROM recMembers WHERE Privilege >= 2
    )
    INSERT INTO recEntrantStatus (entrantId, roundId, judgeId, notified, voted, enterNextRound)
    SELECT m.entrantId, ...
    FROM Members m, Judges j --cross join of your top 8% members and all of your judges
    WHERE ...
    

    您可以通过其他方式执行此操作,例如在您的示例中使用派生表表达式,但我认为 CTE 方法更具可读性。

    【讨论】:

    • 谢谢,我会试试看,看看效果如何。
    • 对我自己的 SQL 稍作调整,看起来效果很好。感谢您的帮助!!!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-04
    • 1970-01-01
    • 1970-01-01
    • 2015-10-05
    • 2021-10-22
    相关资源
    最近更新 更多