Voltar para a lista de artigos Artigos
9 minutos de leitura

Exemplos práticos de quando usar JOINs não-Equi em SQL

Se você acha que duas tabelas em SQL só podem ser unidas usando o campo comum, você ficará entusiasmado em saber que existem outras formas de unir. Os JOINs não-equi usam diferentes tipos de operadores de comparação na condição de JOIN. Neste artigo, vou guiá-lo através de exemplos de JOINs não-equi para mostrar os casos de uso comum para este tipo de JOIN.

Equi JOIN vs. Non-Equi JOIN

Como você costuma unir duas tabelas em SQL? Muito provavelmente, você seleciona o campo comum nestas duas tabelas e as une usando o sinal de igual na condição de união. Por exemplo, você pode combinar o ID do produto da tabela de produtos com o ID do produto da tabela de pedidos ou o sobrenome da tabela de funcionários com o sobrenome da folha de tempos.

Nestes casos, você está usando um equi JOIN, que é apenas um nome fantasia para um join com um sinal de igual na condição de join. Muitos iniciantes em SQL usam equi JOINs e nem mesmo sabem que você pode usar uma condição de não-equidade em JOIN.

Tais junções são chamadas de non-equi JOINs, e também são possíveis em SQL. Quando você une duas tabelas usando outros operadores condicionais, além do sinal de igualdade, entram em jogo os JOINs não-equi. Os operadores de comparação, como <, >, <=, >=, !=, e <> e o operador ENTRE EQUI trabalham perfeitamente para unir tabelas em SQL.

Confira este guia ilustrado do SQL non-equi JOIN para uma melhor compreensão de como ele funciona.

Conhecendo os dados

Antes de mergulhar em diferentes exemplos de JOINs não-equi, vejamos primeiro os dados que estaremos explorando neste artigo. Vamos fazer algumas análises de dados para uma agência imobiliária que administra um negócio de locação. Temos três tabelas em nosso banco de dados imaginário:

  • houses com a identificação da casa, distrito, endereço, número de quartos, e aluguel
  • renters com a identificação do locatário, nome, distrito preferido, número mínimo de quartos necessários e faixa aceitável de aluguel
  • deals com a identificação do negócio, a data, a identificação do locatário, a identificação da casa e a taxa de agente recebida do negócio correspondente

Veja estas três tabelas abaixo.

Houses

iddistrictaddressbedroomsrent
1SouthRose Street, 543000.00
2NorthMain Street, 1232250.00
3SouthRose Street, 543000.00
4WestNice Street, 321750.00
5WestPark Avenue, 1043500.00
6SouthLittle Street, 743000.00
7NorthMain Street, 832100.00

Renters

idnamepreferred_districtmin_bedroomsmin_rentmax_rent
1Helen BossSouth32500.003200.00
2Michael LaneWest21500.002500.00
3Susan SandersWest42500.004000.00
4Tom WhiteNorth32200.002500.00
5Sofia BrownNorth31800.002300.00

Deals

iddaterenter_idhouse_idagent_fee
12020-01-3011600.00
22020-02-0324350.00
32020-03-1235700.00
42020-04-1042450.00

Agora, estamos prontos para passar a exemplos de não-equi JOIN.

Casos de uso para Non-Equi JOINs

Se você nunca usou JOINs não padronizados antes, você pode se perguntar quais são os cenários comuns para a aplicação deste tipo de JOIN não padronizado. Na verdade, há muitos deles. Você pode usar o tipo não-equi JOINs para listar todos os pares (únicos) de itens, identificar duplicatas, listar itens dentro de uma certa faixa de valores ou entre certas datas, computar totais em execução e muito mais.

Vamos começar com os casos de uso mais comuns para os casos de não-qui JOINs.

Listagem de Combinações de Pares

Imaginemos que nossos locatários estão prontos para considerar a possibilidade de dividir uma casa com outra família. Assim, queremos listar todos os pares possíveis de nossos locatários junto com seu distrito preferido para ver quais locatários poderiam potencialmente alugar uma casa juntos. Aqui está a consulta SQL que você poderia usar:

SELECT r1.name, r1.preferred_district, r2.name, r2.preferred_district
FROM renters r1
JOIN renters r2
ON r1.preferred_district = r2.preferred_district AND r1.id != r2.id;

Como você pode ver neste exemplo, juntamos a si mesmo a tabela renters. Usamos duas condições com operadores de comparação diferentes em nossa declaração JOIN:

  • O sinal padrão de igualdade garante que emparelhamos apenas os clientes com o mesmo distrito preferido.
  • O operador de comparação != assegura que o resultado incluirá todos os pares possíveis de locatários, exceto para emparelhar os locatários com eles mesmos

A segunda condição com o != operador faz deste JOIN um JOIN não-equi.

namepreferred_distirctnamepreferred_distirct
Michael LaneWestSusan SandersWest
Susan SandersWestMichael LaneWest
Tom WhiteNorthSofia BrownNorth
Sofia BrownNorthTom WhiteNorth

O resultado parece muito bom, exceto que temos os mesmos pares de locatários listados duas vezes em nossa tabela. Faria mais sentido ter apenas pares únicos em nosso resultado. Esta modificação muito pequena de nossa consulta é um truque útil:

SELECT r1.name, r1.preferred_district, r2.name, r2.preferred_district
FROM renters r1
JOIN renters r2
ON r1.preferred_district = r2.preferred_district AND r1.id < r2.id;
namepreferred_distirctnamepreferred_distirct
Michael LaneWestSusan SandersWest
Tom WhiteNorthSofia BrownNorth

Ao alterar o operador de comparação na segunda condição de junção de != para <, estamos listando apenas os pares nos quais o valor de identificação do primeiro locatário é menor do que o valor de identificação do segundo locatário. Assim, agora temos apenas a linha com Michael Lane (ID 2) listada na primeira coluna e Susan Sanders (ID 3) listada na terceira coluna, e não a linha onde Susan Sanders vem primeiro.

Para listar todos os pares (únicos) de clientes, unimos a tabela de locatários com ela mesma, que é basicamente uma auto-JUNTURA. Para saber mais sobre auto-JUNTOS, veja este guia abrangente com exemplos fáceis de seguir.

Identificando Duplicatas

Outra aplicação comum de JOINs não-equi é encontrar duplicatas em um conjunto de dados. Por exemplo, digamos que queremos verificar se nossa tabela de casas inclui alguma duplicata, ou seja, casas com o mesmo endereço, mas com identificações diferentes.

Nossa consulta será muito semelhante àquela que usamos para listar pares únicos, mas desta vez, nós nos uniremos à tabela de casas:

SELECT h1.id, h1.address, h2.id, h2.address
FROM houses h1
JOIN houses h2
ON h1.address = h2.address AND h1.id < h2.id;

Temos novamente duas condições de união: (1) para verificar se o endereço é o mesmo, e (2) para garantir que listaremos apenas pares únicos com IDs diferentes.

idaddressidaddress
1Rose Street, 53Rose Street, 5

A tabela acima mostra que há uma duplicata em nosso conjunto de dados. A casa localizada na Rua Rose, 5 é mencionada duas vezes na tabela, com ID 1 e ID 3.

Juntando tabelas usando uma gama de valores

Outras aplicações populares de JOINs não-equi incluem a união de duas tabelas usando:

  • O operador BETWEEN para verificar se um determinado valor/data se enquadra em uma faixa específica
  • Operadores de comparação como >= ou <= para verificar a capacidade

Para ver como funcionam na prática estas JOINs não-equi, vamos listar outras casas que podemos sugerir a nossos inquilinos como alternativa. Estas devem ser casas (1) em seu distrito preferido, (2) dentro de sua faixa de preço, (3) com seu número necessário de quartos, e (4) não ocupadas (ou seja, não listadas em nossa tabela de ofertas). Aqui está a consulta SQL que podemos usar:

SELECT r.id, r.name, h.id, h.address, h.rent, h.bedrooms
FROM renters r
JOIN houses h
ON h.district = r.preferred_district
    AND h.rent BETWEEN r.min_rent AND r.max_rent
    AND h.bedrooms >= r.min_bedrooms
WHERE h.id NOT IN (SELECT house_id FROM deals);

Aqui, na condição JOIN, verificamos as três primeiras condições mencionadas acima:

  • Se o distrito da casa corresponde ao distrito preferido do inquilino (condição de igualdade)
  • Se o aluguel está dentro da faixa aceitável do locatário (condição de não-equidade com a faixa de valores)
  • Se o número de dormitórios satisfaz os requisitos mínimos (condição de não-equidade para verificar a capacidade)

Então, na declaração WHERE, usamos uma subquisição para filtrar apenas as casas que presumivelmente estão livres, ou seja, ainda não em nossa deals tabela.

E aqui está a lista de casas que podemos sugerir a nossos clientes (note que a casa com ID 3 é apenas uma duplicata da casa que este cliente está alugando agora):

idnameidaddressrentbedrooms
1Helen Boss6Little Street, 730004
1Helen Boss3Rose Street, 530004
5Sofia Brown7Main Street, 821003

Obtenha mais prática com estes tipos de SQL non-equi JOINs em nosso abrangente curso sobre Cláusulas JOIN em SQL.

Cenários avançados para o uso de casas que não são de Equi

Além das aplicações comuns de JOINs não-equi mencionadas acima, existem alguns cenários mais avançados para a aplicação destes tipos de JOINs. Vamos mergulhar em dois exemplos.

Totais de execução computacional

Um Non-equi JOIN pode ser usado para calcular um total corrente de uma coluna em particular. Por exemplo, digamos que após cada negócio concluído, queremos saber o total da taxa de agente recebida até o momento. Aqui está a consulta SQL que podemos usar:

SELECT d1.date, d1.agent_fee, SUM(d2.agent_fee) AS total_agent_fee
FROM deals d1
JOIN deals d2
ON d1.date >= d2.date
GROUP BY d1.agent_fee, d1.date
ORDER BY d1.date;

Nós nos unimos à tabela deals e usamos uma condição de não-equi JOIN para somar todas as taxas de agente recebidas até a data do negócio. Aqui está o resultado.

dateagent_feetotal_agent_fee
2020-01-30600.00600.00
2020-02-03350.00950.00
2020-03-12700.001650.00
2020-04-10450.002100.00

Observe que uma melhor maneira de calcular um total em execução é usando funções de janela. Nosso guia correspondente explica o que é um total em execução e como escrever uma consulta SQL para calculá-lo. Para a prática, veja o curso interativo LearnSQL.com.br Funções de Janela (Window Functions) em SQL.

Resolvendo Conflitos entre JOINs à ESQUERDA e ONDE

Os Non-equi JOINs também podem ser úteis em algumas situações quando LEFT JOIN combinado com a declaração WHERE não funciona como pretendido. Em particular, é frequente que a condição WHERE "cancele" o LEFT JOIN, fazendo-o funcionar como um INNER JOIN em seu lugar.

Por exemplo, digamos que queremos listar todas as casas de nosso banco de dados junto com a data do acordo correspondente, caso isso ocorra. Também queremos considerar apenas os acordos que aconteceram depois de 1º de março.

Como estamos interessados em listar todas as casas, não importa se elas têm um acordo correspondente, usaremos um LEFT JOIN em nossa consulta SQL. Também acrescentaremos uma condição WHERE para considerar somente os negócios concluídos após uma determinada data:

SELECT h.id, h.address, d.date
FROM houses h
LEFT JOIN deals d
ON h.id = d.house_id
WHERE d.date >= '2020-03-01';
idaddressdate
5Park Avenue, 102020-03-12
2Main Street, 122020-04-10

Como você pode ver, o resultado não é exatamente o que queríamos. A tabela inclui apenas as casas que foram alugadas após 1º de março, ao invés de todas as casas.

Uma solução é mudar a condição WHERE para ON e torná-la uma condição JOIN. Esta será uma junta não-equi, pois utiliza um operador de comparação >=.

SELECT h.id, h.address, d.date
FROM houses h
LEFT JOIN deals d
ON h.id = d.house_id AND d.date >= '2020-03-01';
idaddressdate
5Park Avenue, 102020-03-12
2Main Street, 122020-04-10
6Little Street, 7NULL
4Nice Street, 3NULL
1Rose Street, 5NULL
3Rose Street, 5NULL
7Main Street, 8NULL

Agora vemos todas as casas no resultado, mesmo que elas não tenham acordos correspondentes.

Hora de Praticar Juntas de Não-Equi!

Você aprendeu que o non-equi JOINs pode ser muito útil em diferentes cenários. Você pode listar pares únicos dentro de uma tabela, identificar duplicatas, juntar tabelas usando um intervalo de valores e datas, calcular totais em execução sem usar funções de janela, e muito mais.

Agora, qual é a melhor maneira de praticar Cláusulas JOIN em SQL? Definitivamente, escrevendo código. Então, passemos aos exercícios interativos!

O LearnSQL.com.br Cláusulas JOIN em SQL curso abrange diferentes tipos de JOINs, incluindo JOINs não-equi. Você terá a oportunidade de praticar JOINs não-equi em vários casos de uso. Além disso, o abrangente SQL para Iniciantes curso oferece prática adicional em JOINs não-equi ao explicar a consulta de mais de uma mesa e explorar tópicos mais aprofundados sobre JOINs.

Feliz aprendizagem!