Alternativa ao NOT IN com LEFT JOIN Postgres

25 04 2009

Introdução

Manipular tabelas via SQL é uma arte,  existem diversas formas de fazer a mesma coisa, veja as tabelas abaixo:

+------------+
|   USUARIO  |
+------------+
| usr_cod    |
| usr_login  |
| pss_co     |
+------------+
+------------+
|   PESSOA   |
+------------+
| pss_cod    |
| pss_nome   |
+------------+

O objetivo é descobrir quais pessoas ainda NÃO possuem usuários. Eu resolveria este problema da seguinte forma.

SELECT
   usr_cod
FROM usuario
WERE pss_cod NOT IN
(
   SELECT
      pessoa.pss_cod
   FROM pessoa
      INNER JOIN usuario ON
         usuario.pss_cod = pessoa.pss_cod
)

Qual o Problema Desta Abordagem?

O tempo de resposta desta SQL  é exponecial ao número de registros das tabelas, sendo assim, em tabelas com muitas tuplas se torna inviável.

A Solução

Perguntei ao me amigo Marcio Veronez como ele resolveria este problema e eis que a Luz veio aos meus olhos.

SELECT
   pss_cod
FROM pessoa
   LEFT JOIN usuario ON
      usuario.pss_cod = pessoa.pss_cod
WHERE
   usuario.pss_cod IS NULL

Conclusão

Quando se trata de SQL sempre analise e tente otimizar ao máximo suas consultas pois uma SQL mal planejada é igual a um bumerangue, um dia ela volta.

[]’ Anselmo Battisti


Ações

Information

5 responses

25 04 2009
Mário Nogueira

O “select…minus” não funcionaria neste caso? Por exemplo,

select pss_cod from pessoa MINUS select pss_cod from usuario

(não testei)…

25 04 2009
battisti

dei uma olhada no manual do postgres e achei esse cara aqui

EXCEPT Clause

The EXCEPT clause has this general form:

select_statement EXCEPT [ ALL ] select_statement

select_statement is any SELECT statement without an ORDER BY, LIMIT, FOR UPDATE, or FOR SHARE clause.

The EXCEPT operator computes the set of rows that are in the result of the left SELECT statement but not in the result of the right one.

The result of EXCEPT does not contain any duplicate rows unless the ALL option is specified. With ALL, a row that has m duplicates in the left table and n duplicates in the right table will appear max(m-n,0) times in the result set.

Multiple EXCEPT operators in the same SELECT statement are evaluated left to right, unless parentheses dictate otherwise. EXCEPT binds at the same level as UNION.

Currently, FOR UPDATE and FOR SHARE cannot be specified either for an EXCEPT result or for any input of an EXCEPT.

ainda não testei mas parece que eh a mesma coisa que vc passou

27 04 2009
battisti

Acabei de testar e o except funciona muito bem, mas tem a limitação de que vc pode ter apenas a coluna do código, por exemplo

SELECT pss_cod FROM pessoa EXCEPT SELECT pss_cod FROM funcionario

eu nao consigo trazer na mesma select o nome da pessoa, então em alguns casos da pra usar a idéia do marcio e em outros a idéia do Mário.

[]’s Anselmo Battisti

27 04 2009
mnogueir

Pois, eu falei no “minus” pq estou habituado ao Oracle. Penso que deve ser mais eficiente, mas terá as suas limitações, claro!

12 10 2014
w chojnowie

w chojnowie

Alternativa ao NOT IN com LEFT JOIN Postgres | Anselmo

Deixe uma resposta

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair / Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair / Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair / Alterar )

Foto do Google+

Você está comentando utilizando sua conta Google+. Sair / Alterar )

Conectando a %s




%d blogueiros gostam disto: