在SQL中,如何检查与其他行相似的行值

在SQL中,如何检查与其他行相似的行值,sql,sql-server,Sql,Sql Server,我正在使用SQL Server T-SQL。我有一列包含行值a、AB、ABC、AC。我想删除另一行中包含的任何值。在这种情况下,我会留下ABC和AC,因为A和AB包含在另外两个中 我的想法是获取列的每个值,并使用LIKE搜索整个列,计算返回的结果数。如果它等于1,则它不包含在其他行中 这是一个好方法吗?我这样问是因为我不愿意使用循环/游标 谢谢 以下是从上述解释中提取的代码示例: CREATE TABLE #t (words varchar(10)) INSERT INTO #t VALUES

我正在使用SQL Server T-SQL。我有一列包含行值a、AB、ABC、AC。我想删除另一行中包含的任何值。在这种情况下,我会留下ABC和AC,因为A和AB包含在另外两个中

我的想法是获取列的每个值,并使用LIKE搜索整个列,计算返回的结果数。如果它等于1,则它不包含在其他行中

这是一个好方法吗?我这样问是因为我不愿意使用循环/游标

谢谢

以下是从上述解释中提取的代码示例:

CREATE TABLE #t (words varchar(10))
INSERT INTO #t 
VALUES ('A'),('AB'),('ABC'),('AC')
使用光标,我想我应该做如下操作:

DECLARE @branches TABLE (words varchar(10), n int)
DECLARE @word VARCHAR(10)
DECLARE cursor_word CURSOR

FOR SELECT words FROM #t

OPEN cursor_word;
FETCH NEXT FROM cursor_word INTO @word
WHILE @@FETCH_STATUS = 0
    BEGIN
        INSERT INTO @branches SELECT @word, COUNT(*) FROM #t WHERE words like CONCAT('%', @word ,'%')
        FETCH NEXT FROM cursor_word INTO @word
    END

CLOSE cursor_word
DEALLOCATE cursor_word

SELECT * FROM @branches WHERE n = 1

你可以试试类似的东西

SELECT *
FROM (
    SELECT *
    , Row_Number() OVER(ORDER BY Words) N -- Create identifier for the row
    FROM #t
) t1
LEFT JOIN (
    SELECT *
    , Row_Number() OVER(ORDER BY Words) N -- Create identifier for the row
    FROM #t 
) t2 on t1.N <> t2.n -- Where the identifier is different 
    AND t2.Words LIKE t1.Words + '%' -- Where t2.Words starts with t1.Words
WHERE t2.Words IS NULL -- And there is no match of t2.
我只想用不存在来做这个。这需要表中有一个主键,这是必须的,所以让我假设id为:

我将使用“不存在”,但不需要主键:

select t.*
from t
where not exists (select 1
                  from t t2
                  where t2.words like '%' + t.words + '%' and
                        t2.words <> t.words
                 );

如果没有副本,这在功能上等同于不存在的版本。然而,不存在的情况要好得多。为什么?聚合版本必须遍历每一行以计算计数。不存在的版本可以在第一次匹配时停止-这可以显著减少相似比较的数量。

您使用的是什么特定RDBMS?请提供示例数据并标记数据库。为什么不给它一个详细解释的答案呢。使用某种自我连接有助于所有的回答。
select t.*
from t
where not exists (select 1
                  from t t2
                  where t2.words like '%' + t.words + '%' and
                        t2.words <> t.words
                 );
select t.*
from t
where (select count(*)
       from t t2
       where t2.words like '%' + t.words + '%' 
      ) = 1;