SQL - аналогичные данные в столбце

Есть ли способ найти похожие результаты в столбце. Пример:

Я хочу вернуть запрос из данных таблицы без 4-х зеленых деревьев, потому что нет никаких данных, аналогичных зеленому дереву, но синяя машина похожа на синие машины, а красная кукла похожа на красную тележку.

Как это сделать?

Я использую Microsoft SQL Server Studio Managment Studio

 Gar10 июн. 2016 г., 11:10
Вы должны определить, что такое «сходство», это расстояние Левенштейна? или саундекс? я думаю, что вы нацелены на более простой подход, такой как равенство первых трех букв?

Ответы на вопрос(3)

Этот подход использует очень простое понятие сходства, но может быть расширено до лучшего определения. Заметьте, это не очень эффективно.count(1) + 1 включает в себя базовую фразу.

create table phrases ( phrase varchar(max) )
insert phrases values( 'blue car' ), ( 'blue cars' ), ('green tree' ), ( 'red doll' ), ( 'red dolly' )

create function dbo.fnSimilar( @s1 varchar(max), @s2 varchar(max) )
returns int
begin
    if @s1 = @s2 return 0 -- a phrase is not similar to itself
    if @s1 like @s2 + '%' return 1
    if @s2 like @s1 + '%' return 2
    return 0
end

select x.phrase, similar = count(1) + 1 from 
(
    select p1.phrase from phrases p1
    inner join phrases p2 on dbo.fnSimilar( p2.phrase, p1.phrase ) = 1
) x
group by x.phrase

Результат:

phrase      similar
--------    -------
blue car    2
red doll    2

Как справедливо прокомментировал Гар, вы должны определить, что вы подразумеваете под «сходством». Но если все, что вам нужно, это просто какое-то фиксированное число (в вашем примере 8) равных символов, вы можете сделать следующее:

create table myTest
(
    id int,
    name varchar(20)
);

insert into myTest values(1, 'blue car');
insert into myTest values(2, 'red doll');
insert into myTest values(3, 'blue cars');
insert into myTest values(4, 'green tree');
insert into myTest values(5, 'red dolly');

select left(name,8), count(*) 
from myTest 
group by left(name,8) 
having count(*) > 1;
Решение Вопроса

Вы могли бы использоватьSOUNDEX сделать это.

Пример данных;

CREATE TABLE #SampleData (Column1 int, Column2 varchar(10))
INSERT INTO #SampleData (Column1, Column2)
VALUES
(1,'blue car')
,(2,'red doll')
,(3,'blue cars')
,(4,'green tree')
,(5,'red dolly')

Следующий код будет использоватьsoundex создать список похожих записей вcolumn2, Затем он использует другой подзапрос, чтобы увидеть, сколько вхождений этогоsoundex поле появляется;

SELECT
a.GroupingField
,a.Title
,b.SimilarFields
FROM (
        SELECT
        SOUNDEX(Column2) GroupingField
        ,MAX(Column2) Title --Just return a unique title for this soundex group
        FROM #SampleData
        GROUP BY SOUNDEX(Column2)
      ) a
LEFT JOIN   (
                SELECT
                SOUNDEX(Column2) GroupingField
                ,COUNT(Column2) SimilarFields --How many fields are in the soundex group?
                FROM #SampleData
                GROUP BY SOUNDEX(Column2)
            ) b
ON a.GroupingField = b.GroupingField
WHERE b.SimilarFields > 1

Результаты выглядят так (я оставилsoundex поле, чтобы показать вам, как это выглядит);

GroupingField   Title       SimilarFields
B400            blue cars   2
R300            red dolly   2

Некоторое дальнейшее чтение наsoundex https://msdn.microsoft.com/en-gb/library/ms187384.aspx

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

SELECT
a.GroupingField
,a.Title
,b.SimilarFields
INTO #Duplicates
FROM (
        SELECT
        SOUNDEX(Column2) GroupingField
        ,MAX(Column2) Title --Just return a unique title for this soundex group
        FROM #SampleData
        GROUP BY SOUNDEX(Column2)
      ) a
LEFT JOIN   (
                SELECT
                SOUNDEX(Column2) GroupingField
                ,COUNT(Column2) SimilarFields --How many fields are in the soundex group?
                FROM #SampleData
                GROUP BY SOUNDEX(Column2)
            ) b
ON a.GroupingField = b.GroupingField
WHERE b.SimilarFields > 1

Затем используйте следующий запрос для ссылки на исходные данные;

SELECT
a.GroupingField
,a.Title
,a.SimilarFields
,b.Column1
,b.Column2
FROM #Duplicates a
JOIN #SampleData b
ON a.GroupingField = SOUNDEX(b.Column2)
ORDER BY a.GroupingField

Дал бы следующий результат;

GroupingField   Title       SimilarFields   Column1     Column2
B400            blue cars   2               1           blue car
B400            blue cars   2               3           blue cars
R300            red dolly   2               5           red dolly
R300            red dolly   2               2           red doll

Запомни

DROP TABLE #Differences
 pape10 июн. 2016 г., 13:06
Спасибо, вот и все. У меня только один вопрос. как изменить код, чтобы увидеть, какие данные включаются в группировку, чтобы увидеть синие машины 2, синие машины 2, красную куклу 2, красную тележку 2
 Rich Benner10 июн. 2016 г., 13:29
Хорошо, я вставил полный запрос. Используйте код после редактирования. Обратите внимание, что вам нужно будет сопоставить ваши данные (мои называются #SampleData, ваши будут другими). Если вы выполняете это несколько раз, вам также нужно DROP TABLE #Differences в конце вашего кода
 Rich Benner10 июн. 2016 г., 13:09
Вы можете либо включить этот запрос во внешний запрос, либо вы можете поместить его результаты во временную таблицу, а затем сделать ссылку на исходные данные, основанные на soundex. Если ответ соответствует вашим потребностям, пожалуйста, не стесняйтесь голосовать и пометить ответ как принятый.

Ваш ответ на вопрос