Как сравнить два столбца для равенства в SQL Server?
У меня есть два столбца, которые объединены по определенным критериям, но я также хотел бы проверить два, если два других столбца идентичны, а затем возвращают поле бит, если они есть.
Существует ли более простое решение, чем использование CASE WHEN?
В идеале я мог бы просто использовать:
SELECT Column1 = Column2 AS MyDesiredResult
FROM Table1
INNER JOIN Table2 ON Table1.PrimaryKey = Table2.ForeignKey
Ответы
Ответ 1
Что случилось с CASE для этого? Чтобы увидеть результат, вам понадобится хотя бы байт, и это то, что вы получите с одним символом.
CASE WHEN COLUMN1 = COLUMN2 THEN '1' ELSE '0' END AS MyDesiredResult
должен работать нормально, и для всех целей и целей выполняет то же самое, что и использование битового поля.
Ответ 2
Я бы тоже пошел с CASE WHEN
.
В зависимости от того, что вы на самом деле хотите сделать, могут быть другие варианты, например, использовать внешнее соединение или что-то еще, но это не похоже на то, что вам нужно в этом случае.
Ответ 3
Решение, избегающее CASE WHEN
, заключается в использовании 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
даст NULL
для всех строк, где t1.col2 = t2.col2
(включая NULL
).
Хотя это не более читаемо, чем выражение CASE WHEN
, это ANSI SQL.
Просто ради удовольствия, если вы хотите иметь значения булевого бита 0 и 1 (хотя это не очень читаемо, поэтому не рекомендуется), можно использовать (который работает для всех типов данных):
1/ISNULL(LEN(COALESCE(NULLIF(t1.Col2, t2.Col2),NULLIF(t2.Col2, t1.Col2)))+2,1) as BOOL_BIT_SAME.
Теперь, если у вас есть один из числовых типов данных и бит, в приведенной выше функции LEN
преобразуется в строку сначала, что может быть проблематично, поэтому вместо этого это должно работать:
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
Выше будет работать для целых чисел без CAST
.
ПРИМЕЧАНИЕ. Также в SQLServer 2012 у нас есть функция IIF
.
Ответ 4
Что касается ответа Дэвида Элисондо, это может дать ложные срабатывания. Он также не дает нулей, где значения не совпадают.
код
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
Результаты
t1Col2 t2Col2 MyDesiredResult
----------- ----------- ---------------
123 123 1
234 345 234 <- Not a zero
456 456 1
1 2 1 <- Not a match
Ответ 5
Самый близкий подход, о котором я могу думать, - 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
NULLIF возвращает первое выражение , если два выражения не равны. Если выражения равны, NULLIF возвращает нулевое значение типа первого выражения.
Таким образом, выше запрос возвращает 1 для записей, в которых эти столбцы равны, первое выражение в противном случае.