Problema em SQL

mendex

Power Member
Boas,

a situação é a seguinte tenho uma tabela com várias FKs que podem estar a NULL.

Quando faço um SELECT relacionando a tabela A com as quais se relaciona (B e C), só aparecem as linhas que não tem FKs a NULL, usando um SELECT com a forma:

SELECT ...
FROM A, B
WHERE A.id = B.id
AND A.id = C.id

Também já tentei

SELECT ...
FROM A, B
WHERE A.id = B.id
AND (A.id = C.id OR A.id IS NULL)

mas neste caso a linha da tabela A com valores NULL aparece-me tantas vezes quantas as linhas na tabela C...

Resolvi este problema co dois SELECT (um como o 1º que referi e o outro vai só buscar os que estão a NULL) juntando-os depois numa tabela temporaria...

Mas agora isso não é viável porque são 6 as FKs...

Alguma sugestão?
 
Set Ansi_nulls Off

já descobri que existe uma propriedade que permite mostrar (OFF) ou não (ON) as linhas que têm NULL nas comparações:

SET ANSI_NULLS (ON | OFF)

Mas continua como se nada fosse, não faz efeito...
 
Inner Join

Desde já, obrigado pela resposta.

Pelo que percebi o INNER JOIN faz o mesmo que o WHERE.

O meu problema é que quero comparar duas colunas sem excluir as linhas em que uma das colunas tem o valor NULL.

A alternativa que estou a pensar usar é em vez de por NULL por uma FK com o valor '-1', o que implica que esse registo esteja na outra tabela e que seja corrigido na apresentação dos dados, pelo quenão me parece de todo uma opção...
 
solucao 1:
usar nvl (a.id,-1) transforma todos os id's null em -1

solucao 2:
SELECT ...
FROM A, B
WHERE A.id = B.id
AND A.id = C.id
union all
SELECT ...
FROM A
WHERE a.id is null

a 1ª faz aquilo que queres e depois juntas o que sao null

solucao 3:

SELECT ...
FROM A, B
WHERE A.id += B.id
AND A.id += C.id

+= se a.id nao cruzar ele coloca os registos da tabela a na mesma mas com os valores de b e c a null

obs: Não acho boa ideia ter nulls numa tabela, depois nas contagem e queries alguem se esquecem sempre disso, se poderes opta por colocar a -1 ou -2 (um valor que sabias que nao existe nos dados que recebes)
 
SELECT ...
FROM A LEFT JOIN B ON A.id = B.id
WHERE ...

Esta é a solução, não inventem com -1 e -2, isso são os workarounds.

Breve explicação:
INNER JOIN - A cada registo da tabela da esquerda faz corresponder um da tabela da direita com base no "ON [field1] = [field2]"

LEFT JOIN - A cada registo da tabela da esquerda faz corresponder um da tabela da direita e todos os registos da tabela da esquerda que não tenham correspondência baseada na cláusula ON (NULLs na tabela da direita e afins) aparecem também.

RIGHT JOIN - A cada registo da tabela da direita faz corresponder um da tabela da esquerda, e todos os registos da tabela da direita aparecem tendo ou não correspondência tal como acima.

Existe também o OUTER JOIN mas sinceramente não sei para que serve e nunca precisei de usar, penso que (mas não tenho a certeza) vai buscar todos os registos de ambas as tabelas tenham ou não correspondência.

EDIT: Uma coisa é certa, chaves de tabelas a NULL é contra todos os princípios do sistema relacional, uma chave tem que permitir identificar cada registo da tabela inequívocamente, ou seja, tendo chaves repetidas ou chaves a NULL, perdes este princípio.
 
Última edição:
viva,

obrigado a todos, optei por criar uma opção nas várias tabelas um registo com id=0 que indica "Não especificado", apesar das outras sugestões
 
Back
Topo