Arhn - архитектура программирования

Как сравнить два столбца на предмет равенства в SQL Server?

У меня есть два столбца, которые объединены по определенным критериям, но я также хотел бы проверить, идентичны ли два других столбца, а затем вернуть битовое поле, если они есть.

Есть ли более простое решение, чем использование CASE WHEN?

В идеале я мог бы просто использовать:

    SELECT Column1 = Column2 AS MyDesiredResult
      FROM Table1
INNER JOIN Table2 ON Table1.PrimaryKey = Table2.ForeignKey
27.10.2009

  • Вернуть битовое поле/столбец на выходе? 27.10.2009
  • Действительно отличный вопрос, хотелось бы, чтобы синтаксис работал. ПРИМЕЧАНИЕ. В C++ и других языках C они используют '=' для операции присваивания и == для сравнения. 05.12.2019

Ответы:


1

Что не так с CASE для этого? Чтобы увидеть результат, вам понадобится как минимум байт, и это то, что вы получите с одним символом.

CASE WHEN COLUMN1 = COLUMN2 THEN '1' ELSE '0' END AS MyDesiredResult

должно работать нормально, и во всех смыслах и целях выполняет то же самое, что и использование битового поля.

27.10.2009
  • Я искал что-то короткое. CASE WHEN кажется мне слишком длинным. 27.10.2009
  • Я разместил фактическое заявление CASE WHEN - насколько короткое вам нужно? Разница в длине оператора SQL в несколько символов не имеет смысла, а краткость там, где это не нужно, может значительно усложнить поддержку вашего кода в дальнейшем. Избегать правильной конструкции, чтобы попытаться найти ту, которая на несколько букв короче для ввода, как правило, плохая идея. 27.10.2009
  • Рассмотрите возможность использования чисел, а не символов: CASE WHEN COLUMN1 = COLUMN2 THEN 1 ELSE 0 END AS MyDesiredResult, но я согласен с Кеном, это лучший выбор. 27.10.2009
  • @Rob: я полагал, что Орион будет знать, будет ли 1 или «1» более полезным в реальном использовании. :-) 27.10.2009
  • Когда вы хотите определить только случаи 0 или 1, я обычно использую BIT явно. Просто сделайте так: ... затем приведите (1 как бит) ... 28.10.2009
  • @hainstech: Это работает, конечно. Но в случае, когда вы просто возвращаете данные для просмотра пользователем, скажем, в какой-то сетке, имеет ли это значение? Вы можете привести к биту, но сетке по-прежнему потребуется символ для отображения (8 бит), и если вы не возвращаете ++целую партию++ битовых полей, экономия пропускной способности будет меньше, чем снижение производительности В ролях(). 28.10.2009
  • Я не пытаюсь найти какой-то чрезвычайно краткий способ что-то сказать. COLUMN1 = COLUMN2, ТАК КАК ThirdColumn достаточно длинный, чтобы передать значение. Я нахожу CASE WHEN для этого сценария громоздким. 18.11.2009
  • Я не согласен. COLUMN1 = COLUMN2 AS ThirdColumn не так понятен для тех, кто не знаком с данными, тогда как CASE WHEN чрезвычайно удобочитаем и понятен. Не говорю, что вы не правы, заметьте; только вот не согласен. :-) 18.11.2009
  • В этом случае предпочтительнее возвращать бит, поскольку это гарантирует, что поставщик данных .Net или драйвер ODBC вернут логическое значение, т. е. клиентский код будет сделан более явным, а не будет иметь дело с учетом регистра ('y', 'Y' ) или магические числа (например, =0, ›0 или ›=0 означает истину) 23.12.2014
  • Это не работает, когда COLUMN1 и COLUMN2 равны NULL. 02.01.2019

  • 2

    CASE WHEN — лучший вариант

    SELECT 
      CASE WHEN COLUMN1 = COLUMN2 
        THEN '1' 
        ELSE '0' 
      END 
      AS MyDesiredResult
    FROM Table1
    INNER JOIN Table2 ON Table1.PrimaryKey = Table2.ForeignKey
    
    13.11.2018

    3

    Я бы тоже выбрал CASE WHEN.

    В зависимости от того, что вы на самом деле хотите сделать, могут быть и другие варианты, например, использование внешнего соединения или что-то еще, но в данном случае это не то, что вам нужно.

    27.10.2009

    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
    
    27.10.2009

    5

    Решение избежать 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.

    16.07.2013
  • Как вы сказали, это трудно читать (и поддерживать). Лучше сказать OP, что нет более простого решения, чем использование оператора CASE. Оператор CASE также является частью стандарта ANSI. 23.12.2014

  • 6

    Использование ИИФ? И это зависит от версии SQL Server.

    SELECT
    IIF(Column1 = Column2, 1, 0) AS MyDesiredResult
    FROM Table;
    
    11.05.2020

    7

    Самый близкий подход, который я могу придумать, это 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 для записей, в которых эти столбцы равны, в противном случае первое выражение.

    27.10.2009
  • Смотрите мой ответ, который начинается с ответа Дэвида Элизондо. 27.10.2009
  • Ты прав Роб. функция ISNULL может давать ложные срабатывания. Он должен возвращать что-то, что полностью отличается от контекста значений этих двух столбцов. В моем примере я сравниваю столбцы varchar, поэтому нет проблем с возвратом значения int 1. И, как я уже сказал, мое решение не возвращает ноль (0), но создает различие, когда столбцы равны/не равны. Это самое близкое решение, которое я могу придумать, если он не хочет использовать CASE :) 27.10.2009
  • Новые материалы

    Коллекции публикаций по глубокому обучению
    Последние пару месяцев я создавал коллекции последних академических публикаций по различным подполям глубокого обучения в моем блоге https://amundtveit.com - эта публикация дает обзор 25..

    Представляем: Pepita
    Фреймворк JavaScript с открытым исходным кодом Я знаю, что недостатка в фреймворках JavaScript нет. Но я просто не мог остановиться. Я хотел написать что-то сам, со своими собственными..

    Советы по коду Laravel #2
    1-) Найти // You can specify the columns you need // in when you use the find method on a model User::find(‘id’, [‘email’,’name’]); // You can increment or decrement // a field in..

    Работа с временными рядами спутниковых изображений, часть 3 (аналитика данных)
    Анализ временных рядов спутниковых изображений для данных наблюдений за большой Землей (arXiv) Автор: Рольф Симоэс , Жильберто Камара , Жильберто Кейрос , Фелипе Соуза , Педро Р. Андраде ,..

    3 способа решить квадратное уравнение (3-й мой любимый) -
    1. Методом факторизации — 2. Используя квадратичную формулу — 3. Заполнив квадрат — Давайте поймем это, решив это простое уравнение: Мы пытаемся сделать LHS,..

    Создание VR-миров с A-Frame
    Виртуальная реальность (и дополненная реальность) стали главными модными терминами в образовательных технологиях. С недорогими VR-гарнитурами, такими как Google Cardboard , и использованием..

    Демистификация рекурсии
    КОДЕКС Демистификация рекурсии Упрощенная концепция ошеломляющей О чем весь этот шум? Рекурсия, кажется, единственная тема, от которой у каждого начинающего студента-информатика..