Voltar para a lista de artigos Artigos
8 minutos de leitura

Um Guia Ilustrado para o SQL Non Equi Join

Você sabia que em SQL, um join não tem que ser baseado em partidas idênticas? Neste post, olhamos para o SQL non equi join, que usa operadores 'não iguais' para combinar registros.

Já discutimos vários tipos de join, incluindo self join e CROSS JOIN, INNER JOIN e OUTER JOIN. Esses tipos de uniões normalmente aparecem com o sinal de igual (=). No entanto, algumas juntas utilizam outras condições além do sinal de igual (=). Este é um exemplo de uma junção não equi em SQL, e é sobre isso que vamos falar neste artigo.

O que é um Non Equi Join em SQL?

Se você tem lido os outros posts desta série, você sabe como usar joins SQL para combinar registros com base em combinações de valores exatos. Mas e se você estiver procurando por um registro que não precise de uma correspondência exata? Suponha que você queira combinar registros com base em uma gama de valores. Ou talvez você queira todos os registros que não correspondam a algum valor. Nesses casos, você precisa usar um registro SQL non equi join.

Como um self join, um SQL non equi join não tem uma palavra-chave específica; você nunca verá as palavras NON EQUI JOIN no código SQL de ninguém. Em vez disso, elas são definidas pelo tipo de operador na condição de join: qualquer coisa menos um sinal de igual significa um non equi join. Como você verá na caixa abaixo, às vezes um sinal de igual é parte do operador. Mas em um join SQL non equi, nunca é o operador inteiro por si só. Abaixo, temos alguns operadores non equi join e seus significados:

Operator Meaning
“>” Greater than
“>=” Greater than or equal to
“<” Less than
“<=” Less than or equal to
“!=” Not equal to
”<>” Not equal to (ANSI Standard)
BETWEEN … AND Values in a range between x and y

Finalmente, é bom saber que um SQL non equi join só pode ser usado com uma ou duas tabelas.

Conhecendo nossos dados

Antes de começarmos a descrever as uniões não equi, vamos nos familiarizar com alguns dos dados que estaremos utilizando. Também revisaremos as adesões de eqüis.

Abaixo temos o "person"mesa, que contém registros para as pessoas que estão envolvidas na compra de um apartamento (isto é, um condomínio). Todas as suas colunas são auto-explicativas, mas observe as colunas "min_price" e "max_price". Estas são as faixas de preço da pessoa para um apartamento. A coluna "apartment_id" ligará esta tabela à "apartment" mesa.

id first_name last_name rooms min_price max_price apartment_id
1 Anne Miller 2 40,000 150,000 2
2 John Harris 1 20,000 50,000 2
3 Michael Moore 2 200,000 300,000 6
4 Oliver Watson 4 30,000 100,000 7

A "apartment" tabela armazena informações sobre apartamentos", número de quartos e cidade. Observe que os valores na coluna "id" são basicamente os mesmos que na coluna "apartment_id" acima.

id rooms price city
1 2 30,000 Houston
2 2 45,000 Dallas
3 3 125,000 Chicago
4 5 245,000 Los Angeles
5 4 340,000 San Jose
6 4 220,000 San Diego
7 1 36,000 Cleveland

Agora vamos rever as adesões de eqüis.

O que é um Equi Join SQL?

A maioria dos SQL Joins são equi Joins. Um join equi é qualquer operação de JOIN que usa um sinal de igual e somente um sinal de igual. Você verá consultas que usam mais de uma condição de join; se uma condição é um sinal de igual e a outra não, isso é considerado um join não equi em SQL.

Como já dissemos antes, as uniões equi precisam de uma correspondência exata entre duas colunas. Dê uma olhada na consulta abaixo:

SELECT first_name, last_name, price, city 
FROM person 
JOIN  apartment  ON   apartment.id = person.apartment_id ;

Esta consulta seleciona o primeiro e último nome do cliente, o preço do apartamento e a cidade em que o apartamento está localizado. Usamos um JOIN (também conhecido como INNER JOIN) para combinar os dados da coluna "person" e "apartment"tabelas". Esta união mostra apenas registros que podem ser combinados em ambas as tabelas. Na condição de união, utilizamos o operador igual na coluna "apartment_id" na coluna ".person"tabela e a coluna "id" na coluna "apartment" tabela para encontrar uma correspondência exata.

A tabela resultante contém as seguintes linhas:

first_name last_name price city
Anne Miller 30,000 Houston
John Harris 45,000 Dallas
Michael Moore 220,000 San Diego
Oliver Watson 36,000 Cleveland

Já vimos como funciona uma junção equi. Vamos cavar em SQL non equi joins.

Usando uma junção SQL Non Equi com duas tabelas

SELECT first_name, last_name, min_price, max_price, price, city 
FROM person JOIN apartment ON apartment.id != person.apartment_id
    AND price BETWEEN min_price AND max_price
ORDER BY last_name;

Usamos o operador JOIN para combinar os registros da tabela "person" e "apartment"tabelas". Selecionamos o primeiro e último nome de cada pessoa, os preços mínimo e máximo desejados, e o preço e cidade de todos os apartamentos não escolhidos pelo cliente. Utilizamos o operador BETWEEN... AND para combinar os preços dos apartamentos. Também utilizamos o operador "!=" em um estado com "apartment_id" do "...person" tabela e "id" do "apartment" mesa. Ao fazer isso, removemos o apartamento que foi escolhido da tabela de resultados.

A tabela de resultados tem este aspecto:

first_name last_name min_price max_price price city
John Harris 20,000 50,000 30,000 Houston
John Harris 20,000 50,000 36,000 Cleveland
Anne Miller 40,000 150,000 125,000 Chicago
Michael Moore 200,000 300,000 245,000 Los Angeles
Oliver Watson 30,000 100,000 45,000 Dallas
Oliver Watson 30,000 100,000 30,000 Houston

O apartamento de Dallas escolhido por John Harris não foi mostrado. Note que ele poderia ter escolhido um apartamento em Houston ($30.000) ou em Cleveland ($36.000). Ambos os apartamentos se encaixam em sua faixa de preço de $20.000 - $50.000.

SQL Non Equi Join in Self Join

Agora vamos ver como funciona uma união SQL non equi quando uma mesa é unida a si mesma. Nossos exemplos serão baseados no "playing_cards" tabela mostrada abaixo. Ela contém as seguintes colunas: "id" (um identificador interno), "rank" (o valor nominal ou de face do cartão), e "suit" (o naipe do cartão).

id rank suit
1 A Hearts
2 A Spades
3 A Clubs
4 K Spades
5 K Diamonds
6 Q Clubs
7 J Spades

Estes são os cartões armazenados na tabela "playing_cards" mesa:

Note que temos apenas sete cartas no conjunto.

Vejamos três maneiras de utilizarmos as não-equipamentos nestas circunstâncias.

1. Encontrando todos os pares de cartas

Com base no conjunto de cartas no "playing_cards" mesa, encontraremos todos os pares de cartas possíveis.

Dê uma olhada na consulta:

SELECT c1.rank, c1.suit, c2.rank,c2.suit
FROM playing_cards c1 
JOIN playing_cards c2 ON c1.id != c2.id 
ORDER BY c1.rank;

Na consulta acima, nós nos juntamos à "playing_cards" tabela para si mesma usando os pseudônimos c1 e c2. (Para mais informações sobre auto-adesões e pseudônimos, veja nosso artigo anterior.) Em seguida, usamos o operador de desigualdade "!=", criando um SQL non equi join, para obter todos os pares de cartões possíveis. Este operador mostra pares de cartões em ordem variável e remove pares de cartões idênticos ao mesmo tempo.

A tabela abaixo mostra algumas das filas resultantes. Destacamos as linhas que contêm pares duplicados.

rank suit rank suit
A Spades A Hearts
A Spades A Clubs
A Spades K Spades
A Spades K Diamonds
A Spades Q Clubs
A Spades J Spades
A Clubs A Hearts
A Clubs A Spades
A Clubs K Spades
A Clubs K Diamonds
A Clubs Q Clubs
A Clubs J Spades

Vemos os primeiros 12 de 42 registros totais. A figura abaixo mostra esses pares selecionados:

2. Eliminando Pares Duplicados de Cartões

Os pares de cartas retornados pela última consulta não foram únicos porque o resultado da consulta incluiu pares mostrados em ordem inversa, ou seja, "Ás de Espadas com Ás de Paus" e "Ás de Paus com Ás de Espadas".

Na próxima consulta, só retornaremos pares únicos. A posição das cartas no par não importa.

SELECT c1.rank, c1.suit,c2.rank,c2.suit
FROM playing_cards c1 
JOIN playing_cards c2 ON c1.id < c2.id 
ORDER BY c1.rank;

Como você pode ver, usamos um SQL non equi join com o operador "<" ao invés de "!=". Como resultado, obtivemos pares únicos de cartões.

E estes são os resultados:

rank suit rank suit
A Spades A Hearts
A Clubs A Hearts
A Clubs A Spades
J Spades A Hearts
J Spades A Spades
J Spades A Clubs
J Spades K Spades
J Spades K Diamonds
J Spades Q Clubs
K Spades A Hearts
K Spades A Spades
K Spades A Clubs
K Diamonds A Hearts
K Diamonds A Spades
K Diamonds A Clubs
K Diamonds K Spades
Q Clubs A Hearts
Q Clubs A Spades
Q Clubs A Clubs
Q Clubs K Spades
Q Clubs K Diamonds

Neste caso, 21 registros corresponderam à condição, e todos os pares resultantes apareceram apenas uma vez.

3. Encontrando Pares de Cartões com o Mesmo Fato

Na próxima consulta, selecionaremos pares únicos de cartões com o mesmo naipe (Corações, Espadas, Tacos e Diamantes). Você pode encontrar o operador não equi que usamos?

SELECT c1.rank, c1.suit,c2.rank,c2.suit
FROM playing_cards c1 
JOIN playing_cards c2 ON c1.rank < c2.rank AND c1.suit = c2.suit ;

A consulta acima utilizou duas condições: uma que compara o "ranking" das cartas e outra que compara a coluna "suit".

Dê uma olhada no resultado da consulta.

rank suit rank suit
A Spades K Spades
J Spades K Spades
A Clubs Q Clubs
A Spades J Spades

Apenas quatro registros corresponderam às condições JOIN. A situação é ilustrada abaixo.

Saiba mais sobre SQL

Agora você sabe o que é um SQL non equi join e como ele funciona. Se você estiver interessado em aprender mais sobre SQL, confira LearnSQL.com.br's courses. Você pode praticar suas novas habilidades com exercícios interativos. Você também pode aprender mais sobre SQL join em nossos posts, SQL Joins e Aprendendo Cláusulas JOIN em SQL Usando Situações da Vida Real.