Eu tenho duas tabelas (juntamente com um índice não clusterizado) que podem ser criadas com os comandos abaixo:
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);
Embora tecnicamente minhas tabelas sejam um pouco diferentes e eu esteja participando de algumas outras, esse é um proxy adequado para minha situação.
- Eu gostaria de selecionar todos os
GroupKeys
que não são subconjuntos de outroGroupKey
. - Para um determinado superconjunto, gostaria de obter o máximo
GroupScore
de todos os seus subconjuntos (incluindo ele mesmo). - No caso em que a
GroupKey
contém exatamente o mesmoRecordKeys
que outroGroupKey(s)
, apenas um delesGroupKeys
é capturado (não importa qual). - Qualquer
GroupKey
um que tenha exatamente o mesmoRecordKeys
que outroGroupKey(s)
também terá o mesmoGroupScore
. - Não relacionados
GroupKeys
podem ter a mesma pontuação também.
O seguinte é um exemplo para ilustrar o que estou perguntando:
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
Eu gostaria que a saída fosse a seguinte:
GroupKey RecordCount GroupScore
-------------------------------------
1 3 9.8
192 4 9.8
GroupTable
tem cerca de 75 milhões de linhas e RecordTable
cerca de 115 milhões de linhas; no entanto, após as junções e o WHERE
predicado, tende a haver cerca de 20 mil linhas em um determinado dia.
Peço desculpas se esta pergunta é trivial, mas por algum motivo estou realmente lutando com isso.
Usar subconsultas correlacionadas é uma maneira de obter a saída desejada.
Estou retornando o Grupo com o GroupKey mais baixo quando há uma correspondência, mas isso é arbitrário, pois você diz que não importa.
dados de teste:
consulta:
A subconsulta no SELECT obtém o valor mais alto
GroupScore
apenas dos grupos que são subconjuntos deste grupo ('g1'). Ele consegue isso contando a UNIÃO dosRecordKey
's para o conjunto 'g1' e cada conjunto 'g2'. Se UNION for maior que o conjunto 'g1', deve haver pelo menos umRecordKey
no conjunto 'g2' sem um correspondenteRecordKey
para o conjunto 'g1', então o conjunto 'g2' não é um subconjunto e não deve ser considerado para esta linha.Na cláusula WHERE, há dois casos a serem considerados para filtragem. Em ambos os casos, o conjunto 'g1' só é filtrado se todos os 'g1'
RecordKey
s também estiverem presentes no conjunto 'g3'; e essa verificação é feita contando a união novamente (conforme a cláusula SELECT).Os dois casos são: ① o conjunto 'g1' tem menos
RecordKey
s (g3.RecordCount>g1.RecordCount
; nesse caso filtramos), e ② o conjunto 'g1' é idêntico ao conjunto 'g3' (g3.RecordCount=g1.RecordCount
; nesse caso escolhemos arbitrariamente o conjunto com o inferiorGroupKey
)resultado:
dbfiddle aqui