SQL Server 查找包含重复字母的字符串

7rfyedvj  于 2023-01-29  发布在  其他
关注(0)|答案(5)|浏览(271)

有人能帮我完成这个小任务吗?我需要的是一个存储过程,它可以在表"a"的字符串中找到重复的字母(在一行中),然后创建一个新表"b",其中只包含有重复字母的字符串的id。
大概是这样的

    • 表A**
ID Name   
1  Matt
2  Daave
3  Toom
4  Mike
5  Eddie

从该表中我可以看到DaaveToomEddie在一行中有重复的字母,我想创建一个新表,只列出它们的ID。

    • 表B**
ID     
2
3
5

只有2,3,5,因为这是名称中有重复字母的字符串的ID。
我希望这是可以理解的,并将非常感谢任何帮助。

ekqde3dh

ekqde3dh1#

在您对存储过程的回答中,您有两个错误,一个是列名和LIKE子句之间缺少空格,另一个是搜索参数周围缺少单引号。
我首先创建了一个用户定义的标量函数,如果字符串包含重复的字母,则返回1:

    • 已编辑**
CREATE FUNCTION FindDuplicateLetters
(
    @String NVARCHAR(50)
)
RETURNS BIT
AS
BEGIN

    DECLARE @Result BIT = 0 
    DECLARE @Counter INT = 1

    WHILE (@Counter <= LEN(@String) - 1) 
    BEGIN

    IF(ASCII((SELECT SUBSTRING(@String, @Counter, 1))) = ASCII((SELECT SUBSTRING(@String, @Counter + 1, 1))))
        BEGIN
             SET @Result = 1
             BREAK
        END

        SET @Counter = @Counter + 1 
    END

    RETURN @Result

END
GO

创建函数后,只需从简单的SELECT查询调用它,如下所示:

SELECT 
    * 
FROM
    (SELECT 
        *, 
        dbo.FindDuplicateLetters(ColumnName) AS Duplicates
    FROM TableName) AS a
WHERE a.Duplicates = 1

通过这种组合,您将只获得具有重复字母的行。

fv2wmkja

fv2wmkja2#

在任何版本的SQL中,您都可以使用暴力方法来完成此操作:

select *
from t
where t.name like '%aa%' or
      t.name like '%bb%' or
      . . .
      t.name like '%zz%'

如果归类区分大小写,则用途:

where lower(t.name) like '%aa%' or
      . . .
tf7tbtn2

tf7tbtn23#

有一个办法。
首先创建一个数字表

CREATE TABLE dbo.Numbers
  (
     number INT PRIMARY KEY
  );

INSERT INTO dbo.Numbers
SELECT number
FROM   master..spt_values
WHERE  type = 'P'
       AND number > 0;

有了它,你就可以用

SELECT *
FROM   TableA
WHERE  EXISTS (SELECT *
               FROM   dbo.Numbers
               WHERE  number < LEN(Name)
                      AND SUBSTRING(Name, number, 1) = SUBSTRING(Name, number + 1, 1))
lskq00tm

lskq00tm4#

虽然这是一篇老文章,但值得发表一个比暴力破解方法或标量udf(通常会降低性能)更快的解决方案,使用NGrams8K这是相当简单的。

--sample data
declare @table table (id int identity primary key, [name] varchar(20));
insert @table([name]) values ('Mattaa'),('Daave'),('Toom'),('Mike'),('Eddie');

-- solution #1
select id
from @table
cross apply dbo.NGrams8k([name],1)
where charindex(replicate(token,2), [name]) > 0
group by id;

-- solution #2 (SQL 2012+ solution using LAG)
select id
from
(
  select id, token, prevToken = lag(token,1) over (partition by id order by position)
  from @table
  cross apply dbo.NGrams8k([name],1)
) prep
where token = prevToken
group by id; -- optional id you want to remove possible duplicates.
k97glaaz

k97glaaz5#

另一位伯特福斯道:
选择 *
从t开始
其中www.example.com~'(.)\1';t.name ~ '(.)\1';

相关问题