如何编写SQL查询来检索与参数最接近的匹配项?
假设您在SQL Server 2008 R2中有这样一个表(我们称之为RulesTable):如何编写SQL查询来检索与参数最接近的匹配项?,sql,sql-server,sql-server-2008,tsql,Sql,Sql Server,Sql Server 2008,Tsql,假设您在SQL Server 2008 R2中有这样一个表(我们称之为RulesTable): Id | Type | SubType1 | SubType2 | Value 1 A A1 AA2 10 5 A A1 NULL 50 2 A NULL AA3 20 3 A
Id | Type | SubType1 | SubType2 | Value
1 A A1 AA2 10
5 A A1 NULL 50
2 A NULL AA3 20
3 A NULL NULL 30
4 NULL NULL NULL 40
我将始终查询类型、子类型1和子类型2。如果缺少一个或多个,则假定它为空。查询应始终按照类型、子类型1、子类型2的顺序进行查询,并在搜索过程中缩小搜索范围,然后匹配最近的条目。下面是一些使用场景:
(1) 如果我查询类型='A',子类型1='B',子类型2='C',那么由于在表中找不到'B'或'C',它应该为它们使用null。因此,我将有效地查找Type='A',subpit1=NULL,subpit2=NULL,并且我应该以ID=3的值30结束
(2) 如果我查询类型='A',子类型1='A1',子类型2='C',那么子类型2应该=NULL,因为值不在表中,最接近的匹配是类型='A',子类型1='A1',子类型2=NULL,所以我应该以值=50结束
(3) 如果我查询类型='C',子类型1='C',子类型3='D',那么由于所有这些值都不在我的表中,它们都可以替换为null,因此我将有效地搜索类型=null,子类型1=null,子类型3=null,因此我应该得到值40或Id=4
因此,假设您有参数和结果表:
MyId | Type | SubType1 | SubType2 | Id | Value
1 A B C ? ?
2 A A1 C ? ?
3 C C D ? ?
因此,我只是想了解如何编写一个函数来更新parameters和ResultsTable中的ID/值(使用Type、Subfit1、Subfit2作为参数),并使用上述逻辑提供RulesTable的数据。我想也许可以研究一下距离计算,但我正在寻找如何解决这个问题的想法…这应该能满足您的需要,从最精确到最不精确的顺序:
SELECT *
FROM RulesTable
WHERE ISNULL([Type], @Param1) = @Param1
AND ISNULL(SubType1, @Param2) = @Param2
AND ISNULL(SubType2, @Param3) = @Param3
ORDER BY [Type] DESC,
SubType1 DESC,
SubType2 DESC
这将得到您想要的,从最精确到最不精确的顺序:
SELECT *
FROM RulesTable
WHERE ISNULL([Type], @Param1) = @Param1
AND ISNULL(SubType1, @Param2) = @Param2
AND ISNULL(SubType2, @Param3) = @Param3
ORDER BY [Type] DESC,
SubType1 DESC,
SubType2 DESC
这将得到您想要的,从最精确到最不精确的顺序:
SELECT *
FROM RulesTable
WHERE ISNULL([Type], @Param1) = @Param1
AND ISNULL(SubType1, @Param2) = @Param2
AND ISNULL(SubType2, @Param3) = @Param3
ORDER BY [Type] DESC,
SubType1 DESC,
SubType2 DESC
这将得到您想要的,从最精确到最不精确的顺序:
SELECT *
FROM RulesTable
WHERE ISNULL([Type], @Param1) = @Param1
AND ISNULL(SubType1, @Param2) = @Param2
AND ISNULL(SubType2, @Param3) = @Param3
ORDER BY [Type] DESC,
SubType1 DESC,
SubType2 DESC
下面是函数:
CREATE FUNCTION RuleTableFunction (@Type nvarchar(5), @SubType1 nvarchar(5), @SubType2 nvarchar(5))
RETURNS TABLE
AS
RETURN
(
SELECT
Id
,Value
FROM
table_name
WHERE
(Type = @Type OR Type IS NULL)
and (SubType1 = @SubType1 OR SubType1 IS NULL)
and (SubType2 = @SubType2 OR SubType2 IS NULL)
);
SELECT * FROM RuleTableFunction ('A','B','C');
要调用该函数,请执行以下操作:
CREATE FUNCTION RuleTableFunction (@Type nvarchar(5), @SubType1 nvarchar(5), @SubType2 nvarchar(5))
RETURNS TABLE
AS
RETURN
(
SELECT
Id
,Value
FROM
table_name
WHERE
(Type = @Type OR Type IS NULL)
and (SubType1 = @SubType1 OR SubType1 IS NULL)
and (SubType2 = @SubType2 OR SubType2 IS NULL)
);
SELECT * FROM RuleTableFunction ('A','B','C');
下面是函数:
CREATE FUNCTION RuleTableFunction (@Type nvarchar(5), @SubType1 nvarchar(5), @SubType2 nvarchar(5))
RETURNS TABLE
AS
RETURN
(
SELECT
Id
,Value
FROM
table_name
WHERE
(Type = @Type OR Type IS NULL)
and (SubType1 = @SubType1 OR SubType1 IS NULL)
and (SubType2 = @SubType2 OR SubType2 IS NULL)
);
SELECT * FROM RuleTableFunction ('A','B','C');
要调用该函数,请执行以下操作:
CREATE FUNCTION RuleTableFunction (@Type nvarchar(5), @SubType1 nvarchar(5), @SubType2 nvarchar(5))
RETURNS TABLE
AS
RETURN
(
SELECT
Id
,Value
FROM
table_name
WHERE
(Type = @Type OR Type IS NULL)
and (SubType1 = @SubType1 OR SubType1 IS NULL)
and (SubType2 = @SubType2 OR SubType2 IS NULL)
);
SELECT * FROM RuleTableFunction ('A','B','C');
下面是函数:
CREATE FUNCTION RuleTableFunction (@Type nvarchar(5), @SubType1 nvarchar(5), @SubType2 nvarchar(5))
RETURNS TABLE
AS
RETURN
(
SELECT
Id
,Value
FROM
table_name
WHERE
(Type = @Type OR Type IS NULL)
and (SubType1 = @SubType1 OR SubType1 IS NULL)
and (SubType2 = @SubType2 OR SubType2 IS NULL)
);
SELECT * FROM RuleTableFunction ('A','B','C');
要调用该函数,请执行以下操作:
CREATE FUNCTION RuleTableFunction (@Type nvarchar(5), @SubType1 nvarchar(5), @SubType2 nvarchar(5))
RETURNS TABLE
AS
RETURN
(
SELECT
Id
,Value
FROM
table_name
WHERE
(Type = @Type OR Type IS NULL)
and (SubType1 = @SubType1 OR SubType1 IS NULL)
and (SubType2 = @SubType2 OR SubType2 IS NULL)
);
SELECT * FROM RuleTableFunction ('A','B','C');
下面是函数:
CREATE FUNCTION RuleTableFunction (@Type nvarchar(5), @SubType1 nvarchar(5), @SubType2 nvarchar(5))
RETURNS TABLE
AS
RETURN
(
SELECT
Id
,Value
FROM
table_name
WHERE
(Type = @Type OR Type IS NULL)
and (SubType1 = @SubType1 OR SubType1 IS NULL)
and (SubType2 = @SubType2 OR SubType2 IS NULL)
);
SELECT * FROM RuleTableFunction ('A','B','C');
要调用该函数,请执行以下操作:
CREATE FUNCTION RuleTableFunction (@Type nvarchar(5), @SubType1 nvarchar(5), @SubType2 nvarchar(5))
RETURNS TABLE
AS
RETURN
(
SELECT
Id
,Value
FROM
table_name
WHERE
(Type = @Type OR Type IS NULL)
and (SubType1 = @SubType1 OR SubType1 IS NULL)
and (SubType2 = @SubType2 OR SubType2 IS NULL)
);
SELECT * FROM RuleTableFunction ('A','B','C');
所以我想我必须把这个改成“选择前1*”?否则,这不会返回所有可能可接受的集合,而不一定是最接近的集合吗?正确的,您可以在选择中包括“top 1”以仅获得最准确的记录。因此我想我必须将其更改为“select top 1*”?否则,这不会返回所有可能可接受的集合,而不一定是最接近的集合吗?正确的,您可以在选择中包括“top 1”以仅获得最准确的记录。因此我想我必须将其更改为“select top 1*”?否则,这不会返回所有可能可接受的集合,而不一定是最接近的集合吗?正确的,您可以在选择中包括“top 1”以仅获得最准确的记录。因此我想我必须将其更改为“select top 1*”?否则,这不会返回所有可能可接受的集合,而不一定是最接近的集合吗?正确,您可以在选择中包括“top 1”以仅获取最准确的记录。这不会返回所有可接受的匹配,而不一定是最接近的一个吗?我认为它同时返回这两个集合,它只返回符合以下条件的行“规则”。你应该测试它,看看它是否符合你的要求,以及“规则”是否得到尊重。对我来说,它是。这不一定会返回所有可接受的匹配项,而不一定是最接近的匹配项吗?我想它会同时返回两个匹配项,它只返回符合“规则”的行。你应该测试它,看看这是否符合你的要求,以及是否符合“规则”“我们受到尊重。对我来说是的。这不会返回所有可接受的匹配,而不一定是最接近的匹配吗?我认为它同时会返回这两个匹配,它只返回符合“规则”的行。您应该测试它,看看它是否符合您的要求,以及“规则”是否得到遵守。对我来说是的。这不会返回所有可接受的匹配,而不一定是最接近的匹配吗?我认为它同时会返回这两个匹配,它只返回符合“规则”的行。您应该测试它,看看它是否符合您的要求,以及“规则”是否得到遵守。对我来说是的。