Проверить, содержится ли одно значение столбца в другом значении столбца (TSQL)? - PullRequest
1 голос
/ 03 августа 2010

Эй, у меня есть 2 таблицы с множеством столбцов, и я хочу найти те строки, в которых значение table1.somecolumn содержится в table2.someothercolumn.Пример:

table1.somecolumn имеет Смит, Питер и
table2.someothercolumn имеет peter.smith

Это должно быть совпадение, как бы я сделал такой поиск?

Спасибо:)

Ответы [ 2 ]

2 голосов
/ 03 августа 2010

Вы можете использовать функции SOUNDEX или DIFFERENCE для сопоставления строковых литералов.

Пример:

select difference('peter.green', 'Green, Peter')

возвращает 2, при этом:

Возвращаемое целое число - это количество символов в одинаковых значениях SOUNDEX.Возвращаемое значение в диапазоне от 0 до 4: 0 указывает на слабое или полное отсутствие сходства, а 4 указывает на сильное сходство или одинаковые значения.

См. SOUNDEX и DIFFERENCE разделы в MSDN.

Обновление:

Soundex & Difference может не работать должным образом, если учитывать порядок слов, но если у вас установлены возможности полнотекстовой индексации,вам не нужно создавать индекс, чтобы использовать возможности разбора и анализа слов в полнотекстовом движке.Предполагая, что вы используете SQL Server 2008, следующая функция вернет вам список нормализованных терминов:

SELECT * FROM sys.dm_fts_parser('"Peter Green"', 1033, 0, 0)

С помощью которого вы можете CROSS APPLY до конца вашего запроса.

См. Раздел sys.dm_fts_parser и раздел K. Использование Apply в разделе FROM для получения дополнительной информации.

Пример: (SQL Server Enterprise2008 с включенным полнотекстовым механизмом)

if not OBJECT_ID('Names1', 'Table') is null drop table names1
if not OBJECT_ID('Names2', 'Table') is null drop table names2

create table Names1 
(
    id int identity(0, 1),
    name nvarchar(128)
)
insert into Names1 (name) values ('Green, Peter')
insert into Names1 (name) values ('Smith, Peter')
insert into Names1 (name) values ('Aadland, Beverly')
insert into Names1 (name) values ('Aalda, Mariann')
insert into Names1 (name) values ('Aaliyah')
insert into Names1 (name) values ('Aames, Angela')
insert into Names1 (name) values ('Aames, Willie')
insert into Names1 (name) values ('Aaron, Caroline')
insert into Names1 (name) values ('Aaron, Quinton')
insert into Names1 (name) values ('Aaron, Victor')
insert into Names1 (name) values ('Abbay, Peter')
insert into Names1 (name) values ('Abbott, Dorothy')
insert into Names1 (name) values ('Abbott, Bruce')
insert into Names1 (name) values ('Abbott, Bud')
insert into Names1 (name) values ('Abbott, Philip')
insert into Names1 (name) values ('Abdoo, Rose')
insert into Names1 (name) values ('Abdul, Paula')
insert into Names1 (name) values ('Abel, Jake')
insert into Names1 (name) values ('Abel, Walter')
insert into Names1 (name) values ('Abeles, Edward')
insert into Names1 (name) values ('Abell, Tim')
insert into Names1 (name) values ('Aber, Chuck')

create table Names2
(
    id int identity(200, 1),
    name nvarchar(128)
)
insert into Names2 (name) values (LOWER('Peter.Green'))
insert into Names2 (name) values (LOWER('Peter.Smith'))
insert into names2 (name) values (LOWER('Beverly.Aadland'))
insert into names2 (name) values (LOWER('Mariann.Aalda'))
insert into names2 (name) values (LOWER('Aaliyah'))
insert into names2 (name) values (LOWER('Angela.Aames'))
insert into names2 (name) values (LOWER('Willie.Aames'))
insert into names2 (name) values (LOWER('Caroline.Aaron'))
insert into names2 (name) values (LOWER('Quinton.Aaron'))
insert into names2 (name) values (LOWER('Victor.Aaron'))
insert into names2 (name) values (LOWER('Peter.Abbay'))
insert into names2 (name) values (LOWER('Dorothy.Abbott'))
insert into names2 (name) values (LOWER('Bruce.Abbott'))
insert into names2 (name) values (LOWER('Bud.Abbott'))
insert into names2 (name) values (LOWER('Philip.Abbott'))
insert into names2 (name) values (LOWER('Rose.Abdoo'))
insert into names2 (name) values (LOWER('Paula.Abdul'))
insert into names2 (name) values (LOWER('Jake.Abel'))
insert into names2 (name) values (LOWER('Walter.Abel'))
insert into names2 (name) values (LOWER('Edward.Abeles'))
insert into names2 (name) values (LOWER('Tim.Abell'))
insert into names2 (name) values (LOWER('Chuck.Aber'));

with ftsNamesFirst (id, term) as
(
    select id, terms.display_term
        from names1 cross apply sys.dm_fts_parser('"' + name + '"', 1033, 0, 0) terms
), ftsNamesSecond (id, term) as
(
select id, terms.display_term
        from names2 cross apply sys.dm_fts_parser('"' + name + '"', 1033, 0, 0) terms
)
select * from 
(
    select 
    ROW_NUMBER() over (partition by nfirst.id order by sum(DIFFERENCE(ftsNamesFirst.term, ftsNamesSecond.term)) desc) ranking,
    sum(DIFFERENCE(ftsNamesFirst.term, ftsNamesSecond.term)) Confidence,
    nFirst.id Names1ID,
    nFirst.name Names1Name, 
    nSecond.id Names2ID,
    nSecond.name Names2Name
    from 
    ftsNamesFirst cross join ftsNamesSecond 
    left outer join names1 nFirst on nFirst.id = ftsNamesFirst.id
    left outer join names2 nSecond on nSecond.id = ftsNamesSecond.id 
    where DIFFERENCE(ftsNamesFirst.term, ftsNamesSecond.term) = 4
    group by 
        nFirst.id, nFirst.name, nSecond.id, nSecond.name
) MatchedNames 
where ranking = 1

Выходы:

Где совпадения с наивысшим доверием имеют приоритет (все остальные отфильтровываются с помощью оконного ранжирующего запроса).

Confidence Names1ID Names1Name Names2ID Names2Name
8   0   Green, Peter    200 peter.green
8   1   Smith, Peter    201 peter.smith
8   2   Aadland, Beverly    202 beverly.aadland
8   3   Aalda, Mariann  203 mariann.aalda
4   4   Aaliyah 204 aaliyah
8   5   Aames, Angela   205 angela.aames
8   6   Aames, Willie   206 willie.aames

Это не идеально, но это хорошая отправная точка, с которой его можно настроить, чтобы повысить вероятность успеха.

1 голос
/ 03 августа 2010

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

  1. Используйте вспомогательную таблицу для хранения ключевых слов для каждой записи или записи и поля. Например. table_helper (id int первичный ключ, record_id int, ключевое слово varchar), record_id - ссылка на исходную таблицу Заполните эту таблицу в триггере для table1, table2. Запрос на поиск общих строк представляет собой простое пересечение table_helper с самим собой. Вы можете создать один помощник для table1 и table2 или использовать отдельные таблицы.
  2. Использовать полнотекстовые индексы.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...