Eu quero encontrar todos os grupos em uma tabela que tenham a versão de grupo duplicada. Um grupo pode ter várias versões de grupo. Cada versão do grupo pode ter vários membros. Uma 'versão' de grupo é definida por grpid
e changeDate
. Um grupo considera uma duplicata se TODOS os membros ( userid
, pct
e hobby
) em uma versão de grupo corresponderem a outra versão de grupo dentro do mesmo grupo.
https://dbfiddle.uk/?rdbms=mysql_5.7&fiddle=84eb81a1a71dcee9ad3d0bd91f56120a
A groups
mesa:
Eu iria | agarrar | alteração de data | ID do usuário | pct | passatempo | versão do grupo * |
---|---|---|---|---|---|---|
1 | 1 | 01-01-2020 | 1 | 1 | 1 | 1 |
2 | 1 | 02-01-2020 | 1 | 1 | 2 | 2 |
3 | 1 | 03-01-2020 | 1 | 1 | 1 | 3 |
4 | 2 | 01-01-2020 | 1 | 0,5 | 1 | 4 |
5 | 2 | 01-01-2020 | 2 | 0,5 | 2 | 4 |
6 | 2 | 02-01-2020 | 1 | 0,5 | 1 | 5 |
7 | 2 | 02-01-2020 | 2 | 0,5 | 3 | 5 |
8 | 3 | 01-01-2020 | 1 | 0,5 | 1 | 6 |
9 | 3 | 01-01-2020 | 2 | 0,5 | 2 | 6 |
10 | 3 | 02-01-2020 | 1 | 0,4 | 1 | 7 |
11 | 3 | 02-01-2020 | 2 | 0,6 | 2 | 7 |
12 | 4 | 01-01-2020 | 1 | 0,6 | 1 | 8 |
13 | 4 | 01-01-2020 | 2 | 0,4 | 2 | 8 |
14 | 4 | 02-01-2020 | 1 | 0,6 | 1 | 9 |
15 | 4 | 02-01-2020 | 2 | 0,4 | 2 | 9 |
16 | 5 | 01-01-2020 | 1 | 0,2 | 2 | 10 |
17 | 5 | 01-01-2020 | 2 | 0,5 | 1 | 10 |
18 | 5 | 01-01-2020 | 3 | 0,3 | 2 | 10 |
19 | 6 | 01-01-2020 | 1 | 0,3 | 2 | 11 |
20 | 6 | 01-01-2020 | 2 | 0,5 | 1 | 11 |
21 | 6 | 01-01-2020 | 3 | 0,2 | 2 | 11 |
22 | 6 | 01-02-2020 | 1 | 0,2 | 2 | 12 |
23 | 6 | 01-02-2020 | 2 | 0,5 | 1 | 12 |
24 | 6 | 01-02-2020 | 3 | 0,3 | 2 | 12 |
25 | 6 | 01-03-2020 | 1 | 0,3 | 2 | 13 |
26 | 6 | 01-03-2020 | 2 | 0,3 | 1 | 13 |
27 | 6 | 01-03-2020 | 3 | 0,4 | 2 | 13 |
28 | 7 | 01-01-2020 | 1 | 0,3 | 2 | 14 |
29 | 7 | 01-01-2020 | 2 | 0,5 | 1 | 14 |
30 | 7 | 01-01-2020 | 3 | 0,2 | 2 | 14 |
31 | 7 | 01-02-2020 | 1 | 0,3 | 2 | 15 |
32 | 7 | 01-02-2020 | 2 | 0,5 | 1 | 15 |
33 | 7 | 01-02-2020 | 3 | 0,2 | 2 | 15 |
34 | 7 | 01-03-2020 | 1 | 0,3 | 2 | 16 |
35 | 7 | 01-03-2020 | 2 | 0,3 | 1 | 16 |
36 | 7 | 01-03-2020 | 3 | 0,4 | 2 | 16 |
37 | 8 | 01-02-2020 | 1 | 0,3 | 1 | 17 |
38 | 8 | 01-03-2020 | 1 | 0,3 | 1 | 18 |
39 | 8 | 01-03-2020 | 3 | 0,4 | 2 | 18 |
* Número exclusivo da versão do grupo apenas para visualização.
Resultado deve ser:
grpid
1
4
7
Explicação:
- grpid 1 - existem 3 versões de grupo (de 1 membro) - 1 e 3 duplicadas porque userid, pct e hobby são iguais
- grpid 2 - existem 2 versões de grupo (de 2 membros) - não duplicado porque hobby não é igual entre 5 e 7
- grpid 3 - existem 2 versões de grupo (de 2 membros) - não duplicado porque o pct é diferente entre todos os membros
- grpid 4 - existem 2 versões de grupo (de 2 membros) - todos os membros são duplicados porque userid, pct e userid são iguais
- grpid 5 - existe apenas um grupo de 3 membros - não duplicado
- grpid 6 - existem 3 versões de grupo (de 3 membros) - não duplicado - o pct mudou para cada membro do grupo entre as versões
- grpid 7 - existem 3 versões de grupo (de 3 membros) - duplicado porque userid, pct e userid são iguais entre 28-30 e 31-33
- grpid 8 - existem 2 versões de grupo uma com um membro e outra com 2 membros - não duplicada porque há outro membro nesse grupo
Estou usando o MySQL 5.7.
Espero que isso forneça uma resposta:
Isso implementa a divisão relacional "comum":
Resultado:
Isso implementa a divisão relacional exata , o que resulta em um código ainda mais complicado. Seu caso, onde os agrupamentos/versões são determinados por duas colunas
(grpid, changeDate)
, faz com que pareça ainda mais complicado.Testado em dbffdle.uk
Pergunta 1:
Consulta 2 que usa a
GROUP_CONCAT
função do MySQL:Você pode usar uma junção interna para isso
Fyi mysql 8 não gosta de grupos como nome de tabela e deve ser colocado em backticks
E as linhas id = 2 e id = 4, também são "idênticas e se enquadram em sua regra
db<>fique aqui
Isso usa as cláusulas GROUP BY e HAVING para agrupar, respectivamente, os valores nos campos que você especificou para condensar as duplicatas em uma linha e filtrar onde a contagem de linhas condensadas em cada agrupamento era maior que 1 (em outras palavras, onde havia duplicatas) .