如何设计存储过程或函数返回多表UNION查询的单个ODD值?
嘿,看起来你需要从多个不同的赛事赔率表里,根据指定的fixid、type和res参数拿到唯一的ODD值对吧?我给你整理了两种最优方案,还有性能优化的小技巧,一起来看看~
最优解决方案:创建标量函数或存储过程返回单个ODD值
方案一:标量值函数(推荐用于查询内直接调用)
标量函数可以直接返回单个值,非常契合你的需求。我们用TOP 1确保只返回一个结果(如果UNION后意外出现多个值,会取第一条;如果无匹配结果则返回NULL,你可以根据业务逻辑调整):
CREATE FUNCTION GetSingleOddValue( @fixid INT, -- 请根据实际字段类型调整参数类型 @type VARCHAR(50), @res VARCHAR(20) ) RETURNS DECIMAL(10,2) -- 请根据ODD字段的实际类型调整返回值类型 AS BEGIN DECLARE @odd DECIMAL(10,2) SELECT TOP 1 @odd = ODD FROM ( SELECT ODD FROM SOCCER_PREMATCH_ODDS WHERE FIXID = @fixid AND TYPE = @type AND RES = @res UNION SELECT ODD FROM LIVE_ODDS WHERE FIXID = @fixid AND TYPE = @type AND RES = @res UNION SELECT ODD FROM PREMATCH_BASKETBALL_ODDS WHERE FIXID = @fixid AND TYPE = @type AND RES = @res UNION SELECT ODD FROM LIVE_BASKETBALL_ODDS -- 补全你未写完的实时篮球赔率表 WHERE FIXID = @fixid AND TYPE = @type AND RES = @res ) AS CombinedOdds RETURN @odd END
调用方式:
SELECT dbo.GetSingleOddValue(123, 'WIN', 'HOME') AS SingleOdd
方案二:存储过程(适合独立执行场景)
如果你更倾向于用存储过程,这里提供两个版本:带输出参数的版本,以及直接返回结果集的版本。
带输出参数的版本
CREATE PROCEDURE GetSingleOddValueProc @fixid INT, @type VARCHAR(50), @res VARCHAR(20), @outOdd DECIMAL(10,2) OUTPUT AS BEGIN SET NOCOUNT ON; SELECT TOP 1 @outOdd = ODD FROM ( SELECT ODD FROM SOCCER_PREMATCH_ODDS WHERE FIXID = @fixid AND TYPE = @type AND RES = @res UNION SELECT ODD FROM LIVE_ODDS WHERE FIXID = @fixid AND TYPE = @type AND RES = @res UNION SELECT ODD FROM PREMATCH_BASKETBALL_ODDS WHERE FIXID = @fixid AND TYPE = @type AND RES = @res UNION SELECT ODD FROM LIVE_BASKETBALL_ODDS WHERE FIXID = @fixid AND TYPE = @type AND RES = @res ) AS CombinedOdds END
调用方式:
DECLARE @resultOdd DECIMAL(10,2) EXEC GetSingleOddValueProc @fixid=123, @type='WIN', @res='HOME', @outOdd=@resultOdd OUTPUT SELECT @resultOdd AS SingleOdd
返回结果集的版本
CREATE PROCEDURE GetSingleOddValueProc @fixid INT, @type VARCHAR(50), @res VARCHAR(20) AS BEGIN SET NOCOUNT ON; SELECT TOP 1 ODD AS SingleOdd FROM ( SELECT ODD FROM SOCCER_PREMATCH_ODDS WHERE FIXID = @fixid AND TYPE = @type AND RES = @res UNION SELECT ODD FROM LIVE_ODDS WHERE FIXID = @fixid AND TYPE = @type AND RES = @res UNION SELECT ODD FROM PREMATCH_BASKETBALL_ODDS WHERE FIXID = @fixid AND TYPE = @type AND RES = @res UNION SELECT ODD FROM LIVE_BASKETBALL_ODDS WHERE FIXID = @fixid AND TYPE = @type AND RES = @res ) AS CombinedOdds END
调用方式:
EXEC GetSingleOddValueProc @fixid=123, @type='WIN', @res='HOME'
关键性能优化建议
为了让这个查询跑得更快,一定要给每个表的FIXID、TYPE、RES三个字段创建复合索引,比如:
-- 足球赛前赔率表索引 CREATE NONCLUSTERED INDEX IX_SOCCER_PREMATCH_ODDS_FixTypeRes ON SOCCER_PREMATCH_ODDS (FIXID, TYPE, RES) INCLUDE (ODD) -- 把ODD字段加入包含列,避免回表查询 -- 实时足球赔率表索引 CREATE NONCLUSTERED INDEX IX_LIVE_ODDS_FixTypeRes ON LIVE_ODDS (FIXID, TYPE, RES) INCLUDE (ODD) -- 篮球赛前赔率表索引 CREATE NONCLUSTERED INDEX IX_PRE_BASKETBALL_ODDS_FixTypeRes ON PREMATCH_BASKETBALL_ODDS (FIXID, TYPE, RES) INCLUDE (ODD) -- 实时篮球赔率表索引 CREATE NONCLUSTERED INDEX IX_LIVE_BASKETBALL_ODDS_FixTypeRes ON LIVE_BASKETBALL_ODDS (FIXID, TYPE, RES) INCLUDE (ODD)
这样数据库可以直接通过索引定位到符合条件的行,无需全表扫描,大幅提升查询速度。
另外,如果你的业务逻辑能保证每个参数组合在所有表中最多只有一个匹配项,建议把UNION换成UNION ALL——UNION会做去重排序,而UNION ALL只是简单合并结果,性能会更好。
异常处理补充
如果业务要求必须返回有效值(不能为NULL),可以在函数或存储过程中添加判断逻辑:
-- 在标量函数中添加示例 IF @odd IS NULL BEGIN -- 抛出错误提示 RAISERROR('No matching ODD value found for the given parameters', 16, 1) -- 或者返回默认值:SET @odd = 0.00 END
内容的提问来源于stack exchange,提问作者civesuas_sine
相关产品推荐
相关产品推荐

