SQL Server聚合可能包含多个副本的数据

时间:2018-07-01 10:14:13

标签: sql-server aggregate-functions

我正在使用某些软件,需要使用SQL Server进行大型数据聚合。该软件正在帮助人们更好地玩扑克。我目前正在使用的查询看起来像这样:

Select H, sum(WinHighCard + ChopHighCard + WinPair + ChopPair + Win2Pair + Chop2Pair + Win3OfAKind + Chop3OfAKind + WinStraight + ChopStraight + WinFlush + ChopFlush + WinFullHouse + ChopFullHouse + WinQuads + ChopQuads + WinStraightFlush + ChopStraightFlush) / Count(WinStraightFlush) as ResultTotal
 from [FlopLookup].[dbo].[_5c3c3d] 
                inner join[FlopLookup].[dbo].[Lookup5c3c3d] on [FlopLookup].[dbo].[Lookup5c3c3d].[id] = [FlopLookup].[dbo].[_5c3c3d].[id] 
                where (H IN (1164, 1165, 1166) ) AND 
                (V IN (1260, 1311))
                Group by H;

这很好,是我发现要完成的最快的方法。问题是我需要以某种方式增强功能,以允许聚合包括V的多个实例。因此,例如,在上述查询中,一次包含两次来自1260和1311的数据而不是一次包含来自1260和1311的数据,并且1311次。但是显然只是在说

V IN (1260, 1260, 1311, 1311, 1311)

不起作用,因为每个唯一值在IN子句中仅被计数一次。

我想出了一个解决该问题的方法,该方法虽然有效,但似乎很笨拙。我创建了另一个查找表,该表只接受0到1325之间的值,并将它们分配给名为V1的字段,并且对于每个V1,都有100个V2值,例如对于V1 = 1260,V2值的范围是从126000到126099。然后在主查询中,我加入该表并进行如下查询:

Select H, sum(WinHighCard + ChopHighCard + WinPair + ChopPair + Win2Pair + Chop2Pair + Win3OfAKind + Chop3OfAKind + WinStraight + ChopStraight + WinFlush + ChopFlush + WinFullHouse + ChopFullHouse + WinQuads + ChopQuads + WinStraightFlush + ChopStraightFlush) / Count(WinStraightFlush) as ResultTotal
 from [FlopLookup].[dbo].[_5c3c3d] 
                inner join[FlopLookup].[dbo].[Lookup5c3c3d] on [FlopLookup].[dbo].[Lookup5c3c3d].[id] = [FlopLookup].[dbo].[_5c3c3d].[id] 
                inner join[FlopLookup].[dbo].[VillainJoinTable] on [FlopLookup].[dbo].[VillainJoinTable].[V1] = [FlopLookup].[dbo].[_5c3c3d].[V]
                where (H IN (1164, 1165, 1166) ) AND 
                (V2 IN (126000, 126001, 131100, 131101, 131102) )
                Group by H;

因此,尽管它起作用,但速度很慢。感觉效率低下,因为它多次添加数据,而使用乘法的方式可能更合适,例如,而不是传入126000、126001、126002、126003、126004、126005、126006、126007,而是传入在原始查询中输入1260,然后将其乘以8。但是我无法找到一种方法来完成此操作。

任何帮助将不胜感激。谢谢。

编辑-应Livius的要求在评论中添加了更多信息

H代表“英雄”,并在_5c3c3d表中作为smallint代表玩家持有的两张牌(例如AcKd,Js4h等)。 V代表“ Villain”,与Hero相似,但代表对手持有的相似编码的卡。编码和解码在代码中进行。这两个字段构成_5c3c3d表的聚集索引。该表中的其余字段是Id,这是另一个smallint,用于与表Lookup5c3c3d联接,该表包含英雄手与翻牌5c3c3d的恶棍之手的所有净值信息。

V2只是我为解决此问题而创建的表中的一个字段,该表具有一个名为VillainJoinTable的表,该表具有V1(通过连接直接映射到_5c3c3d中的V)和V2(可能包含100个数字)每个V1(例如,当V1为1260时,可能包含126000、126001 ... 126099)。这是为了允许我创建一个“ IN”子句,该子句可以有效地多次搜索同一V的股权信息。

以下是一些屏幕截图:

三个表的结构

Structure of the three tables

_5c3c3d的某些数据

Some data from _5c3c3d

Lookup5c3c3d的一些数据

Some data from Lookup5c3c3d

来自VillainJoinTable的一些数据

Some data from VillainJoinTable

0 个答案:

没有答案