SQL Server 2014: HASHBYTES возвращает другое значение для одной и той же строки

Я работаю с CSV-файлом адресов, которые ежедневно загружаются на FTP-сайт. Адресные записи состоят из Address_Line1, Address_Line2, City, State, Zip_Code и Country. В CSV есть несколько повторяющихся адресов. Моя задача - сравнить все адреса в файле CSV с существующим измерением адресов, а затем загрузить только новые адреса. Чтобы сделать это, я сначала загружаю из CSV в промежуточную таблицу, затем запускаю следующий запрос, чтобы сгенерировать хеш для сравнения:

UPDATE STG_ADDRESS
SET ADDRESS_HASH = HASHBYTES(
    'SHA1'
    ,ISNULL(ADDRESS_LINE1, 'N/A') + 
    ISNULL(ADDRESS_LINE2, 'N/A') +
    ISNULL(CITY, 'N/A') +
    ISNULL(STATE, 'N/A') +
    ISNULL(ZIP_CODE, 'N/A') + 
    ISNULL(COUNTRY, 'N/A'));

Это работает нормально, за одним исключением. Функция HASHBYTES генерирует несколько хешей для одного и того же точного адреса. Для сегодняшней загрузки я выполнил следующий запрос и получил 37 разных адресов:

SELECT DISTINCT 
    ISNULL(ADDRESS_LINE1, 'N/A') 
    + ISNULL(ADDRESS_LINE2, 'N/A')
    + ISNULL(CITY, 'N/A')
    + ISNULL(STATE, 'N/A')
    + ISNULL(ZIP_CODE, 'N/A') 
    + ISNULL(COUNTRY, 'N/A')

FROM STG_ADDRESS

После обновления с помощью Hash я запустил следующий запрос и получил 43 записи:

SELECT DISTINCT 
    ISNULL(ADDRESS_LINE1, 'N/A') 
    + ISNULL(ADDRESS_LINE2, 'N/A')
    + ISNULL(CITY, 'N/A')
    + ISNULL(STATE, 'N/A')
    + ISNULL(ZIP_CODE, 'N/A') 
    + ISNULL(COUNTRY, 'N/A')
    ,ADDRESS_HASH

FROM STG_ADDRESS

Я дважды проверил это с помощью следующего запроса:

SELECT DISTINCT 
    ISNULL(ADDRESS_LINE1, 'N/A') 
    + ISNULL(ADDRESS_LINE2, 'N/A')
    + ISNULL(CITY, 'N/A')
    + ISNULL(STATE, 'N/A')
    + ISNULL(ZIP_CODE, 'N/A') 
    + ISNULL(COUNTRY, 'N/A')
    ,COUNT(ADDRESS_HASH)

FROM STG_ADDRESS

GROUP BY
    ISNULL(ADDRESS_LINE1, 'N/A') 
    + ISNULL(ADDRESS_LINE2, 'N/A')
    + ISNULL(CITY, 'N/A')
    + ISNULL(STATE, 'N/A')
    + ISNULL(ZIP_CODE, 'N/A') 
    + ISNULL(COUNTRY, 'N/A')

HAVING COUNT(ADDRESS_HASH) > 1

И увидел, что есть шесть адресов, которые SQL-сервер считает одинаковыми при выполнении SELECT DISTINCT, но считает иначе, когда создает хэш.

Есть ли сценарий, где одна и та же строка может привести к созданию другого хеша? Если так, что можно сделать, чтобы исправить проблему?

1 ответ

Решение

Пробел и регистр должны быть нормализованы перед вызовом HASHBYTES, потому что они всегда чувствительны к регистру. По умолчанию сравнения строк во время обычных операций SQL не чувствительны к регистру (вы можете изменить это с помощью параметра сервера COLLATION).

LTRIM(RTRIM(TOLOWER(@value)))
Другие вопросы по тегам