Como comparar duas colunas para igualdade no servidor SQL?
Tenho duas colunas que se unem em certos critérios, mas também gostaria de verificar duas para ver se as outras duas colunas são idênticas e, em seguida, retornar um pequeno campo se forem.
Há uma solução mais simples do que usar o CASE quando?
idealmente eu poderia usar:
SELECT Column1 = Column2 AS MyDesiredResult
FROM Table1
INNER JOIN Table2 ON Table1.PrimaryKey = Table2.ForeignKey
5 answers
CASE WHEN COLUMN1 = COLUMN2 THEN '1' ELSE '0' END AS MyDesiredResult
Deve funcionar bem, e para todos os efeitos realiza a mesma coisa que usar um campo bit.
Uma solução que evite CASE WHEN
deve utilizar COALESCE
.
SELECT
t1.Col2 AS t1Col2,
t2.Col2 AS t2Col2,
COALESCE(NULLIF(t1.Col2, t2.Col2),NULLIF(t2.Col2, t1.Col2)) as NULL_IF_SAME
FROM @t1 AS t1
JOIN @t2 AS t2 ON t1.ColID = t2.ColID
NULL_IF_SAME
a coluna indicará NULL
para todas as linhas em que t1.col2 = t2.col2
(incluindo NULL
).
Embora esta não seja mais legível do que CASE WHEN
expressão, é ANSI SQL.
Só por Diversão, se se quiser ter valores de bit booleanos de 0 e 1( embora não seja muito legível, portanto não recomendado), pode-se usar (que funciona para todos os tipos de Dados):
1/ISNULL(LEN(COALESCE(NULLIF(t1.Col2, t2.Col2),NULLIF(t2.Col2, t1.Col2)))+2,1) as BOOL_BIT_SAME.
Agora se tiver um dos tipos de dados numéricos e quiser bits, na função LEN
acima, converte-se em cadeia de caracteres primeiro o que pode ser problemático,por isso, em vez disso, isto deve funcionar:
1/(CAST(ISNULL(ABS(COALESCE(NULLIF(t1.Col2, t2.Col2),NULLIF(t2.Col2, t1.Col2)))+1,0)as bit)+1) as FAST_BOOL_BIT_SAME_NUMERIC
Acima funcionará para inteiros sem CAST
.
Nota: também em SQLServer 2012, temos IIF
função.
Código
DECLARE @t1 TABLE (
ColID int IDENTITY,
Col2 int
)
DECLARE @t2 TABLE (
ColID int IDENTITY,
Col2 int
)
INSERT INTO @t1 (Col2) VALUES (123)
INSERT INTO @t1 (Col2) VALUES (234)
INSERT INTO @t1 (Col2) VALUES (456)
INSERT INTO @t1 (Col2) VALUES (1)
INSERT INTO @t2 (Col2) VALUES (123)
INSERT INTO @t2 (Col2) VALUES (345)
INSERT INTO @t2 (Col2) VALUES (456)
INSERT INTO @t2 (Col2) VALUES (2)
SELECT
t1.Col2 AS t1Col2,
t2.Col2 AS t2Col2,
ISNULL(NULLIF(t1.Col2, t2.Col2), 1) AS MyDesiredResult
FROM @t1 AS t1
JOIN @t2 AS t2 ON t1.ColID = t2.ColID
Resultados
t1Col2 t2Col2 MyDesiredResult
----------- ----------- ---------------
123 123 1
234 345 234 <- Not a zero
456 456 1
1 2 1 <- Not a match
A abordagem mais próxima que consigo pensar é NULLIF:
SELECT
ISNULL(NULLIF(O.ShipName, C.CompanyName), 1),
O.ShipName,
C.CompanyName,
O.OrderId
FROM [Northwind].[dbo].[Orders] O
INNER JOIN [Northwind].[dbo].[Customers] C
ON C.CustomerId = O.CustomerId
GO
O NULLIF devolve a primeira expressão se as duas expressões não forem iguais . Se as expressões forem iguais, NULLIF devolve um valor nulo do tipo da primeira expressão.
Então, a consulta acima irá voltar 1 para os registos em que essas colunas sejam iguais, a primeira expressão caso contrário.