【发布时间】:2021-05-12 10:21:38
【问题描述】:
我和我的朋友尝试建立一个用于足球台球投注的高级模型。由于 Excel 的限制,我们发现 SQL 是一个更好的选择。我们已经设法实现了我们的目标,但这个过程每次大约需要 20-30 分钟,我认为这是因为过程效率低下。我将尝试解释我们正在做什么,希望你们聪明的人可以为我指明正确的方向,以采取更有效的方法。
让我们开始向您展示 SQL 数据库的外观。我们有一张主桌Rows,其中包含 13 场足球比赛的所有可能的比赛结果组合:
CREATE TABLE [dbo].[Rows](
[RowID] [int] NULL,
[Match_1] [int] NULL,
[Match_2] [int] NULL,
[Match_3] [int] NULL,
[Match_4] [int] NULL,
[Match_5] [int] NULL,
[Match_6] [int] NULL,
[Match_7] [int] NULL,
[Match_8] [int] NULL,
[Match_9] [int] NULL,
[Match_10] [int] NULL,
[Match_11] [int] NULL,
[Match_12] [int] NULL,
[Match_13] [int] NULL
);
INSERT INTO Rows
(RowID, Match_1, Match_2, Match_3, Match_4, Match_5, Match_6, Match_7, Match_8, Match_9, Match_10, Match_11, Match_12, Match_13)
VALUES
(1,1,1,1,1,1,1,1,1,1,1,1,1,1),
(2,1,1,1,1,1,1,1,1,1,1,1,1,3),
(3,1,1,1,1,1,1,1,1,1,1,1,1,2),
(4,1,1,1,1,1,1,1,1,1,1,1,3,1),
(5,1,1,1,1,1,1,1,1,1,1,1,3,3),
(6,1,1,1,1,1,1,1,1,1,1,1,3,2),
(7,1,1,1,1,1,1,1,1,1,1,1,2,1),
(8,1,1,1,1,1,1,1,1,1,1,1,2,3),
(9,1,1,1,1,1,1,1,1,1,1,1,2,2),
(10,1,1,1,1,1,1,1,1,1,1,3,1,1);
所以这相当于大约 160 万行。这些值代表 1=主场胜利,3=平局,2=客场胜利。
现在我们需要选择哪些可能是本周的结果。我们使用 Excel 来获取我们的数据并跟踪要使用的条件。 Excel 使用为每个游戏周调整的数字填充 SQL 查询,因此我们只需复制并粘贴到 SQL Server Management Studio 中。我们有大约 1300 个条件,我们每周测试和应用大约 600-700 个条件。为了能够添加这 13 个特定游戏的数据,我们使用计算列。因此,我们向表中添加了大约 700 个计算列。示例:
ALTER TABLE dbo.Rows ADD Group1 AS ((CASE WHEN [Match_1] = 1 THEN 0 WHEN [Match_1] = 3 THEN 0 WHEN [Match_1] = 2 THEN 0 END) + (CASE WHEN [Match_2] = 1 THEN 1 WHEN [Match_2] = 3 THEN 0 WHEN [Match_2] = 2 THEN 0 END) + (CASE WHEN [Match_3] = 1 THEN 0 WHEN [Match_3] = 3 THEN 0 WHEN [Match_3] = 2 THEN 0 END) + (CASE WHEN [Match_4] = 1 THEN 0 WHEN [Match_4] = 3 THEN 0 WHEN [Match_4] = 2 THEN 0 END) + (CASE WHEN [Match_5] = 1 THEN 0 WHEN [Match_5] = 3 THEN 0 WHEN [Match_5] = 2 THEN 0 END) + (CASE WHEN [Match_6] = 1 THEN 0 WHEN [Match_6] = 3 THEN 0 WHEN [Match_6] = 2 THEN 0 END) + (CASE WHEN [Match_7] = 1 THEN 0 WHEN [Match_7] = 3 THEN 0 WHEN [Match_7] = 2 THEN 0 END) + (CASE WHEN [Match_8] = 1 THEN 0 WHEN [Match_8] = 3 THEN 0 WHEN [Match_8] = 2 THEN 0 END) + (CASE WHEN [Match_9] = 1 THEN 0 WHEN [Match_9] = 3 THEN 0 WHEN [Match_9] = 2 THEN 0 END) + (CASE WHEN [Match_10] = 1 THEN 0 WHEN [Match_10] = 3 THEN 0 WHEN [Match_10] = 2 THEN 0 END) + (CASE WHEN [Match_11] = 1 THEN 0 WHEN [Match_11] = 3 THEN 0 WHEN [Match_11] = 2 THEN 0 END) + (CASE WHEN [Match_12] = 1 THEN 0 WHEN [Match_12] = 3 THEN 0 WHEN [Match_12] = 2 THEN 0 END) + (CASE WHEN [Match_13] = 1 THEN 0 WHEN [Match_13] = 3 THEN 0 WHEN [Match_13] = 2 THEN 0 END));
所以基本上,它的作用是在 CASE 表达式的帮助下计算每行有多少期望的结果。对于Group1,我们只需要您将在下面的 SELECT 查询中看到的一款游戏。
最后一步(花费大部分时间)是SELECT所有满足我们所有要求的行。如前所述,它使用了大约 700 个不同的条件,因此我们必须使用 WITH-clauses 将其拆分为多个查询。
WITH Step1 AS (
SELECT [Rows].[RowID],[Rows].[Match_1],[Rows].[Match_2],[Rows].[Match_3],[Rows].[Match_4],[Rows].[Match_5],[Rows].[Match_6],[Rows].[Match_7],[Rows].[Match_8],[Rows].[Match_9],[Rows].[Match_10],[Rows].[Match_11],[Rows].[Match_12],[Rows].[Match_13]
FROM Rows
WHERE [Rows].[Group1] >= 1 AND [Rows].[Group1] <= 1
)
SELECT [Step1].[RowID],[Step1].[Match_1],[Step1].[Match_2],[Step1].[Match_3],[Step1].[Match_4],[Step1].[Match_5],[Step1].[Match_6],[Step1].[Match_7],[Step1].[Match_8],[Step1].[Match_9],[Step1].[Match_10],[Step1].[Match_11],[Step1].[Match_12],[Step1].[Match_13]
INTO FinalRows
FROM Step1
;
我应该从哪里简化这一点并提高效率?你对我的前进有什么建议吗?理想的情况是最多在 5-10 分钟内完成。
【问题讨论】:
-
看起来您在这里遇到了一些主要的非规范化问题。应该有一个
Match列,而不是 13 个。 -
感谢您的评论。所以它最适合将 Match_1-Match_13 连接为单列,对吗?
-
不,每场比赛 1 行。我建议阅读范式。一个好的设计至少应该遵守3NF。
-
我正在努力理解您正在尝试做的事情 - 从概念上讲,我认为您已经过火了。我不能完全确定你的问题,但这是我对你的看法:你想根据你得到的 13 场比赛中涉及的球队之间最有可能的结果来投注池 - 你有一些历史数据代表匹配团队之间的结果,您希望交叉引用它以获得本周最有可能的结果(基本上是在玩赔率)。听起来对吗?如果不是,您使用什么数据作为驱动因素来确定您的赌注?
-
我一开始就不明白在数据库中输入 3^13 行的意义——当然你想要一个数据库模式,上面写着
Home Team, Away Team, Result,然后输入你的历史数据并查询这个使用主队/客队?当它基本上只是一个简单的赔率游戏时,我不明白池如何具有“高级”建模。