where 子句中的缩写
Abbreviation in where clause
像对待 Sta 一样对待缩写。等于圣诞老人,或妈妈。等于 Maria 或 Ma.
SELECT * FROM Table1 A WITH(NOLOCK) WHERE A.Name LIKE '%ma%'
此查询是针对 Maria 的,但问题是它还包含一个包含 marie
的名称
情况 1:用户输入 ma
结果将是 maria
、ma
和 ma.
,反之亦然。
案例 2:用户输入 Maria
输出将是 Ma. Teresa
或 Maria Teresa
或 Ma Teresa
并且 sta
场景也是如此。
情况 3:用户输入 sta
结果将是 santa
、sta.
和 sta
,反之亦然。
情况 4:用户输入没有缩写的正常名称 (Jose) 结果会像 Jose
对这个问题有什么想法吗?或者解决这个问题的最佳方法是什么?
谢谢。
你有一个句点作为缩写,所以这可能会达到你想要的效果:
WHERE ' ' + A.Name + ' ' LIKE '% Ma. %'
一种方法是列出所有缩写及其对应的内容。
本质上,构建一个单独的 table 将缩写扩展为全名。
Table Abbrevs
列 Abbrev, Name
.
对于您的示例,它将包含这些行:
Abbrev Name
ma Maria
ma Ma.
ma. Maria
ma. Ma
sta Santa
sta Sta.
sta. Santa
sta. sta
然后查找用户提供的字符串以及该名称的所有可能同义词。像这样:
DECLARE @ParamInput nvarchar(255);
SET @ParamInput = 'ma';
SELECT *
FROM YourTable
WHERE
YourTable.Name = @ParamInput
OR YourTable.Name IN
(
SELECT Abbrevs.Name
FROM Abbrevs
WHERE Abbrevs.Abbrev = @ParamInput
)
;
您可以让用户定义和编辑 Abbrevs
table。
如果用户输入和 table 都可能有缩写,并且您需要使用 LIKE
,而不是简单的 =
进行搜索,那么我会做类似正在关注。
仍然会有一个单独的 table 来扩展缩写词(或者,更确切地说,是特定名称的可能缩写词列表):
Abbrev Name
ma Maria
ma. Maria
sta Santa
sta. Santa
除此之外,我还有一个规范化给定名称的函数。该函数将搜索给定名称中可能的缩写并展开它们。
例如,给定 Ma. Teresa
,函数将 return Maria Teresa
使用 Abbrevs
table.
您的主 table 有一个字段 Name
,其原始名称可以包含缩写。我将添加另一个(计算的或持久的)列 NormalizedName
,该列将由该函数填充。在实践中,我将这样的列作为一个普通的持久列,并编写了一个触发器,当主 Name
列发生变化时更新它的值。规范化的一个步骤是将所有字符串变为大写。您可以在其中构建一些其他规则,例如丢弃所有点、逗号、破折号和其他此类符号,将双 space 替换为单个 space,等等
您仅向用户显示原始 Name
值。
当用户提供要搜索的名称时,我使用相同的函数规范化给定名称,并使用简单的
在 NormalizedName
列中搜索规范化值
WHERE NormalizedName LIKE '%'+@ParamNormalizedName+'%'
此函数用于检查搜索是否包含 ma
、ma.
...
CREATE FUNCTION [dbo].[StringContains]
(
-- Add the parameters for the function here
@String1 VARCHAR(MAX),
@String2 VARCHAR(MAX)
)
RETURNS BIT
AS
BEGIN
-- Declare the return variable here
DECLARE @Result BIT = 0
DECLARE @IsContain INT = 0
DECLARE @Equivalents TABLE
(
ID INT IDENTITY(1,1),
Text1 VARCHAR(50),
Text2 VARCHAR(50)
)
INSERT INTO @Equivalents (Text1, Text2)
VALUES ('ma. ','maria'),
('ma. ','ma '),
('ma ','maria'),
('sta. ','santa'),
('sta. ','sta '),
('sta ','santa')
DECLARE @ID INT = 1
DECLARE @TOTAL INT = (SELECT COUNT(1) FROM @Equivalents)
WHILE @ID <= @TOTAL
BEGIN
DECLARE
@Temp1 VARCHAR(MAX) = @String1,
@Temp2 VARCHAR(MAX) = @String2,
@Text1 VARCHAR(50),
@Text2 VARCHAR(50)
SELECT TOP 1
@Text1 = Text1,
@Text2 = Text2
FROM @Equivalents
WHERE ID = @ID
IF @Temp1 LIKE '%'+@Text1+'%' AND @Temp2 LIKE '%'+@Text2+'%'
BEGIN
SET @String2 = REPLACE(@Temp2,@Text2,@Text1)
END
ELSE IF @Temp1 LIKE '%'+@Text2+'%' AND @Temp2 LIKE '%'+@Text1+'%'
BEGIN
SET @String2 = REPLACE(@Temp2,@Text1,@Text2)
END
IF @String1 LIKE '%'+@String2+'%'
BEGIN
SET @IsContain += 1
END
SET @ID += 1
END
SET @Result = (CASE WHEN @IsContain > 0 THEN 1 ELSE 0 END)
RETURN @Result
END
这是查询。
DECLARE @Text VARCHAR(MAX) = 'maria'
SELECT TOP 100 FullName,* FROM dbo.Table1 WITH(NOLOCK)
WHERE dbo.StringContains(FullName,@Text) = 1
像对待 Sta 一样对待缩写。等于圣诞老人,或妈妈。等于 Maria 或 Ma.
SELECT * FROM Table1 A WITH(NOLOCK) WHERE A.Name LIKE '%ma%'
此查询是针对 Maria 的,但问题是它还包含一个包含 marie
情况 1:用户输入 ma
结果将是 maria
、ma
和 ma.
,反之亦然。
案例 2:用户输入 Maria
输出将是 Ma. Teresa
或 Maria Teresa
或 Ma Teresa
并且 sta
场景也是如此。
情况 3:用户输入 sta
结果将是 santa
、sta.
和 sta
,反之亦然。
情况 4:用户输入没有缩写的正常名称 (Jose) 结果会像 Jose
对这个问题有什么想法吗?或者解决这个问题的最佳方法是什么?
谢谢。
你有一个句点作为缩写,所以这可能会达到你想要的效果:
WHERE ' ' + A.Name + ' ' LIKE '% Ma. %'
一种方法是列出所有缩写及其对应的内容。
本质上,构建一个单独的 table 将缩写扩展为全名。
Table Abbrevs
列 Abbrev, Name
.
对于您的示例,它将包含这些行:
Abbrev Name
ma Maria
ma Ma.
ma. Maria
ma. Ma
sta Santa
sta Sta.
sta. Santa
sta. sta
然后查找用户提供的字符串以及该名称的所有可能同义词。像这样:
DECLARE @ParamInput nvarchar(255);
SET @ParamInput = 'ma';
SELECT *
FROM YourTable
WHERE
YourTable.Name = @ParamInput
OR YourTable.Name IN
(
SELECT Abbrevs.Name
FROM Abbrevs
WHERE Abbrevs.Abbrev = @ParamInput
)
;
您可以让用户定义和编辑 Abbrevs
table。
如果用户输入和 table 都可能有缩写,并且您需要使用 LIKE
,而不是简单的 =
进行搜索,那么我会做类似正在关注。
仍然会有一个单独的 table 来扩展缩写词(或者,更确切地说,是特定名称的可能缩写词列表):
Abbrev Name
ma Maria
ma. Maria
sta Santa
sta. Santa
除此之外,我还有一个规范化给定名称的函数。该函数将搜索给定名称中可能的缩写并展开它们。
例如,给定 Ma. Teresa
,函数将 return Maria Teresa
使用 Abbrevs
table.
您的主 table 有一个字段 Name
,其原始名称可以包含缩写。我将添加另一个(计算的或持久的)列 NormalizedName
,该列将由该函数填充。在实践中,我将这样的列作为一个普通的持久列,并编写了一个触发器,当主 Name
列发生变化时更新它的值。规范化的一个步骤是将所有字符串变为大写。您可以在其中构建一些其他规则,例如丢弃所有点、逗号、破折号和其他此类符号,将双 space 替换为单个 space,等等
您仅向用户显示原始 Name
值。
当用户提供要搜索的名称时,我使用相同的函数规范化给定名称,并使用简单的
在NormalizedName
列中搜索规范化值
WHERE NormalizedName LIKE '%'+@ParamNormalizedName+'%'
此函数用于检查搜索是否包含 ma
、ma.
...
CREATE FUNCTION [dbo].[StringContains]
(
-- Add the parameters for the function here
@String1 VARCHAR(MAX),
@String2 VARCHAR(MAX)
)
RETURNS BIT
AS
BEGIN
-- Declare the return variable here
DECLARE @Result BIT = 0
DECLARE @IsContain INT = 0
DECLARE @Equivalents TABLE
(
ID INT IDENTITY(1,1),
Text1 VARCHAR(50),
Text2 VARCHAR(50)
)
INSERT INTO @Equivalents (Text1, Text2)
VALUES ('ma. ','maria'),
('ma. ','ma '),
('ma ','maria'),
('sta. ','santa'),
('sta. ','sta '),
('sta ','santa')
DECLARE @ID INT = 1
DECLARE @TOTAL INT = (SELECT COUNT(1) FROM @Equivalents)
WHILE @ID <= @TOTAL
BEGIN
DECLARE
@Temp1 VARCHAR(MAX) = @String1,
@Temp2 VARCHAR(MAX) = @String2,
@Text1 VARCHAR(50),
@Text2 VARCHAR(50)
SELECT TOP 1
@Text1 = Text1,
@Text2 = Text2
FROM @Equivalents
WHERE ID = @ID
IF @Temp1 LIKE '%'+@Text1+'%' AND @Temp2 LIKE '%'+@Text2+'%'
BEGIN
SET @String2 = REPLACE(@Temp2,@Text2,@Text1)
END
ELSE IF @Temp1 LIKE '%'+@Text2+'%' AND @Temp2 LIKE '%'+@Text1+'%'
BEGIN
SET @String2 = REPLACE(@Temp2,@Text1,@Text2)
END
IF @String1 LIKE '%'+@String2+'%'
BEGIN
SET @IsContain += 1
END
SET @ID += 1
END
SET @Result = (CASE WHEN @IsContain > 0 THEN 1 ELSE 0 END)
RETURN @Result
END
这是查询。
DECLARE @Text VARCHAR(MAX) = 'maria'
SELECT TOP 100 FullName,* FROM dbo.Table1 WITH(NOLOCK)
WHERE dbo.StringContains(FullName,@Text) = 1