获得 TOP 8 PERCENT 然后插入另一个 table
Get TOP 8 PERCENT then insert into another table
我有一个场景,我需要根据每个 artist/record 的分数计算前 8% 的记录,这些分数由 3 个类别的 5 位不同评委确定。
为此,我在存储过程中使用了以下内容
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 条记录。
在前几轮中,我只是选择了 'ALL' 个具有位字段用作标记的参赛者,以指示他们将进入下一轮。我用以下代码做到了这一点:
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 位评委添加一条新记录?
不幸的是,将 CROSS JOIN SELECT 替换为检索前 8% 的 CROSS JOIN 并不是一个简单的例子。
有什么建议吗??
使用识别 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 ...
您可以通过其他方式执行此操作,例如在您的示例中使用派生的 table 表达式,但我认为 CTE 方法更具可读性。
我有一个场景,我需要根据每个 artist/record 的分数计算前 8% 的记录,这些分数由 3 个类别的 5 位不同评委确定。
为此,我在存储过程中使用了以下内容
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 条记录。
在前几轮中,我只是选择了 'ALL' 个具有位字段用作标记的参赛者,以指示他们将进入下一轮。我用以下代码做到了这一点:
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 位评委添加一条新记录?
不幸的是,将 CROSS JOIN SELECT 替换为检索前 8% 的 CROSS JOIN 并不是一个简单的例子。
有什么建议吗??
使用识别 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 ...
您可以通过其他方式执行此操作,例如在您的示例中使用派生的 table 表达式,但我认为 CTE 方法更具可读性。