我有两个表(以及一个非聚集索引)可以使用以下命令创建:
CREATE TABLE GroupTable
(
GroupKey int NOT NULL PRIMARY KEY,
RecordCount int NOT NULL,
GroupScore float NOT NULL
);
CREATE TABLE RecordTable
(
RecordKey varchar(10) NOT NULL,
GroupKey int NOT NULL,
PRIMARY KEY(RecordKey, GroupKey)
);
CREATE UNIQUE INDEX ixGroupRecord ON RecordTable(GroupKey, RecordKey);
虽然从技术上讲,我的桌子略有不同,而且我加入了其他几张桌子,但这很适合我的情况。
- 我想选择所有
GroupKeys
不是另一个子集的GroupKey
。 - 对于给定的超集,我想获取其
GroupScore
所有子集(包括其自身)的最大值。 - 在 a包含与another
GroupKey
完全相同的情况下,只有其中一个被抓取(哪个并不重要)。RecordKeys
GroupKey(s)
GroupKeys
- 任何与另一个
GroupKey
完全相同的对象也将具有相同的.RecordKeys
GroupKey(s)
GroupScore
- 非相关
GroupKeys
也可以有相同的分数。
下面是一个例子来说明我在问什么:
GroupTable RecordTable
GroupKey RecordCount GroupScore RecordKey GroupKey
------------------------------------ ---------------------
1 3 6.2 A 1
29 2 9.8 A 29
95 3 6.2 A 95
192 4 7.1 A 192
B 1
B 29
B 95
B 192
C 1
C 95
D 192
E 192
我希望输出如下:
GroupKey RecordCount GroupScore
-------------------------------------
1 3 9.8
192 4 9.8
GroupTable
大约有 7500 万行,RecordTable
大约有 11500 万行;但是,在连接和WHERE
谓词之后,给定的一天往往有大约 20k 行。
如果这个问题微不足道,我深表歉意,但出于某种原因,我真的很难解决这个问题。
使用相关子查询是获得所需输出的一种方法。
当有匹配项时,我将返回具有最低 GroupKey 的组,但这是任意的,因为你说这无关紧要。
测试数据:
询问:
GroupScore
SELECT 中的子查询仅从作为该 ('g1') 组子集的那些组中获取最高值。它通过计算RecordKey
'g1' 集和每个 'g2' 集的 's 的 UNION 来实现这一点。如果 UNION 大于 'g1' 集合,则RecordKey
'g2' 集合中必须至少有一个没有对应RecordKey
'g1' 集合,因此 'g2' 集合不是子集,不应考虑这一排。在 WHERE 子句中,有两种情况需要考虑进行过滤。
RecordKey
在任何一种情况下,仅当所有“g1”也存在于“g3”集中时,“g1”集才会被过滤;并且此检查是通过再次计算联合来实现的(根据 SELECT 子句)。这两种情况是:① 'g1' 集合有更少
RecordKey
的 s(g3.RecordCount>g1.RecordCount
; 在这种情况下我们过滤),以及 ② 'g1' 集合与 'g3' 集合相同(g3.RecordCount=g1.RecordCount
; 在这种情况下我们任意选择具有降低GroupKey
)输出:
dbfiddle在这里