Introdução

Dizemos que uma consulta SQL possui uma junção do tipo self-join, quando uma tabela faz um “cruzamento de dados” com ela própria na cláusula FROM. Caso não exista uma condição de junção (ex: INNER JOIN) entre as duas instâncias da mesma tabela, o resultado da consulta produzirá todos os arranjos possíveis dos dados da tabela. Na seção a seguir, apresentamos um exemplo prático.

Arranjos de n elementos 2 a 2

Considere a tabela T_TIME, apresentada na Figura 1 que possui apenas um campo (NOME) e quatro registros armazenados. Suponha que os registros correspondem a 4 times de futebol que estão disputando um campeonato.

Tabela T_TIME

Figura 1. Tabela T_TIME

Nosso objetivo é elaborar uma consulta SQL que faça o arranjo 2 a 2 desses quatro elementos. Ou seja, queremos gerar todos os grupos de 2 times possíveis, considerando também todas as diferentes ordens em que os mesmos p. O caminho a seguir é simples: basta utilizar na consulta um self-join sem condição de junção, ou seja, basta repetir o nome da tabela duas vezes sem ligar o campo NOME na cláusula WHERE. Além disso, é importante observar que você deve dar dois apelidos diferentes - como T1 e T2 - para cada uma das duas instâncias da tabela. A consulta apresentada na Listagem 1 quase alcança o objetivo que desejamos. Os resultados são mostrados na Figura 2. Para a consulta ficar perfeita, falta corrigir um pequeno detalhe, comentado logo após a figura.

Listagem 1: Arranjo dos Elementos 2 a 2 (consulta com erro)


SELECT * FROM T_TIME A1, T_TIME A2
Resultado da Consulta Errada

Figura 2. Resultado da Consulta Errada

Observando a Figura 2 é possível perceber que um erro aconteceu: o arranjo de 4 elementos em grupos de 2 deveria resultar em 4! / (4-2)! = 12 conjuntos (essa é a “famosa” fórmula da análise combinatória). No entanto, a consulta retornou 16 conjuntos.

O que deu errado? Bem, o problema é que a consulta acabou produzindo quatro resultados errados, onde um mesmo nome de time foi repetido no par (MARCELONA com MARCELONA, REAL MADREAD com REAL MADREAD, INTER DE MELÃO com INTER DE MELÂO e MANCHETE UNIDA com MANCHETE UNIDA).

Felizmente, a correção para o problema é muito simples. Como você já deve estar imaginando, basta acrescentarmos uma condição na cláusula WHERE capaz de impedir a produção de linhas onde o nome dos dois times é o mesmo. Observe que não se trata de uma condição de junção, pois condições de junção não são utilizadas em SQLs que produzem arranjos de elementos. A condição da cláusula WHERE é na verdade uma condição de restrição, usada para eliminar linhas indesejadas. A consulta corrigida é mostrada na Listagem 2 e os resultados logo abaixo, na Figura 3.

Listagem 2: Arranjo dos Elementos 2 a 2 (consulta corrigida)


SELECT * FROM T_TIME A1, T_TIME A2 
WHERE A1.NOME <> A2.NOME
 
Resultado da Consulta Corrigida

Figura 3. Resultado da Consulta Corrigida

Com esta correção, finalizamos o artigo. Nos próximos artigos, mostraremos outros exemplos de análise combinatória com SQL. Até lá!