更新: 我将第一部分改写为基于setbased的方法:
declare @AllRunnersString nvarchar(200) ='2342;1228;1075;266;423;2849;1690;488;162;1153;1666'
DECLARE @pairs table
(p1 int,p2 int)
insert into @pairs(p1, p2)
select sp1.value as p1, sp2.value as p2
from dbo.split(';', @AllRunnersString) sp1
inner join dbo.split(';', @AllRunnersString) sp2
on sp1.value <> sp2.value
这会生成对。
Head2Head获取id并返回一个包含所有具有两个id的事件的表。 @rtn表( eventid int, p1 int, p2 int, ldiff float, pdiff float, 胜利者 )
我需要接受所有这些事件,并将它们存储在表格中,用于@pairs的所有组合。
使用基于过程的方法,我会在@pairs上运行游标,并使用过程计算每对的值并插入到最终表中。
也许这部分有一种基于设定的方法..
答案 0 :(得分:0)
您的描述很容易理解,如果您的功能 getHead2Head 的文字也可用,那么仍然很好。还提供一些数据来证明你的问题。
我读到了你的解释,我有一些建议
为什么你使用2循环,而不是制作一个循环。
在这种情况下,您可以更好地控制使用光标,而不是在适当时使用光标,最后不需要设置更新以进行重置。
快速查询的主要问题是与每个查询以及每个条件相关的问题。
您可以为临时表提供主键,这样可以获得快速结果。(创建主表像普通表一样简单)
答案 1 :(得分:0)
最好切换到使用表值参数或XML传递参数,这自然支持多个值而不是将它们塞进字符串中,但是因为你已经有了这个部分而且它是& #34;工作&#34;对你而言,我们不管它。
以下内容应相同:
declare @AllRunnersString nvarchar(200)
='2342;1228;1075;266;423;2849;1690;488;162;1153;1666'
declare @rtn table
(
eventid int,
player1 int,
player2 int,
lengthdiff float,
placediff float,
winner int
)
declare @playerids table
(
playerid int
)
-- parse string into table
insert into @playerids(playerid)
select value
from split(';', @AllRunnersString)
insert into @rtn(eventid, player1, player2, lengthdiff, placediff, winner)
select eventid, player1, player2, lengthdiff, placediff, winner
from
@playerids p1
inner join
@playerids p2
on
p1.playerid != p2.playerid
cross apply
getHead2Head(p1.playerid, p2.playerid, 3)
如果我们可以取消对getHead2Head
的调用并将其内容直接包含在此查询中,则可能还有其他机会可以改进这一点。
答案 2 :(得分:0)
您需要重建一个真正的数据库任务 - 构建循环以匹配记录 - 在TSQL中。不要使用过程代码,使用set代码,让服务器执行循环和填充。他会做得更好,没有进攻。例如,如果您想随意加入只有一个合作伙伴/候选人对的合作伙伴,您可以执行以下操作:
WITH player_combination
AS (
--Cross Joins selects all combinations of mutually different players
SELECT p.playerid [partner], c.playerid candidate,newid() random_id
FROM @playerid p, @playerid c
WHERE p.playerid<>c.playerid
)
SELECT pc.[partner],pc.candidate
FROM player_combination pc
JOIN (SELECT [partner], max(random_id) random_id --Select the record with max random_id
FROM player_combination
GROUP BY [partner]) tmp ON tmp.[partner]=pc.[partner] AND tmp.random_id=pc.random_id
如果您可以选择免费播放器的最大ID,则声明更容易:
WITH player_combination
AS (
--Cross Joins selects all combinations of mutually different players
SELECT p.playerid [partner], c.playerid candidate
FROM @playerid p, @playerid c
WHERE p.playerid<>c.playerid
)
SELECT pc.[partner],pc.candidate
FROM player_combination pc
JOIN (SELECT [partner], max(candidate) candidate --Select the record with max candidate id
FROM player_combination
GROUP BY [partner]) tmp ON tmp.[partner]=pc.[partner] AND tmp.random_id=pc.random_id
我很确定你也可以摆脱getHead2Head功能。