Estou executando uma subconsulta correlacionada para saber a listagem de fornecedores (pelo Vendor Name) que estão em diferentes cidades, estados, ou seja, queremos saber os fornecedores que não possuem cidade e estado em comum com outros fornecedores. Parecia que uma autojunção era a coisa certa a fazer.
Apenas dicas, se possível, por favor.
A tabela de fornecedores é:
Vendors(VendorID P, VendorCity, VendorState, VendorName,...)
Isto é o que eu tenho:
Select VendorName, VendorCity, VendorState from Vendors AS V1 where
VendorCity, VendorState NOT IN (Select VendorCity, VendorState FROM
Vendors AS V2 where V2.VendorID <> V1.VendorID)
Esta é a mensagem de erro que recebo:
Msg 4145, Nível 15, Estado 1, Linha 2 Uma expressão de tipo não booleano especificada em um contexto onde uma condição é esperada, próximo a ','.
Não vejo por que há uma referência a tipos booleanos, já que não é um EXISTS ou outra consulta relacionada.
A sintaxe para IN(...) é:
Com:
Isso significa que apenas 1 coluna é permitida em ambos os lados. Mesmo uma lista de expressões é considerada como 1 tabela fictícia com 1 coluna para valores de expressão semelhantes a:
Com 2 colunas você pode usar uma subconsulta com EXISTS :
No geral esta subconsulta sempre retorna 0 linha ou 1 ou mais linhas com 1 pois ela só precisa saber se existe 1 ou mais linhas com a mesma Cidade e Estado. O valor não é importante porque ele olha apenas para o número de linhas (=> se EXISTE 1 ou mais linhas), portanto, o
SELECT 1
. O teste já foi feito naWHERE
cláusula interna.Eu acho que VendorId é o PK. Um índice em VendorCity e VendorState ajudaria.
Como você está aprendendo e se ainda não o conhece, também pode observar o uso de APPLY ( CROSS APPLY e OUTER APPLY ). Eu deixo você experimentar e brincar com ele.
Conforme declarado na outra resposta , o SQL Server atualmente não permite a sintaxe desejada. Outros produtos fazem e há uma solicitação de item Connect aqui:
Adicione suporte para construtores de valor de linha padrão ANSI .
Ainda é possível usar
NOT IN
emboraIsso fornece um plano semelhante, com um operador anti-semi-join, como
NOT EXISTS
Use CONCAT(...):
Para abordar um comentário deixado por Martin Smith :
Os
ABC | DEF
anagramas não seriam um problema em um cenário real, pois não acho que existam combinações comoABCD | EF
, por exemplo. O problema com os índices pode ser facilmente resolvido criando um índice contendo apenas as colunas "VendorCity, VendorState".Como alternativa, ele poderia criar sua própria tabela de hash para essas 2 colunas e armazenar o hash gerado como um campo extra na mesma tabela.
Eu adoraria ver um benchmark comparando o desempenho das soluções fornecidas (incluindo a minha).