具有动态搜索条件的SQL搜索查询
我有一个旧的动态SQL查询,如下所示,其中where子句中的条件根据搜索文本动态追加 示例1:搜索字符串“AMX AC-DIN-CS3括号” 这里有3个And子句,因为搜索字符串中有3个部分(用空格分隔(AMX、AC-DIN-CSS3和括号) 示例2:搜索字符串“AMX AC-DIN-CS3” 这里有2个And子句,因为搜索字符串中有2个部分(AMX、AC-DIN-CS3) 我想摆脱动态sql,创建一个查询,根据搜索字符串得到与上面相同的结果,但得到的结果不同 与例1相当,但有额外结果 这里我得到了额外的记录,如(所有制造商为'AMX'的产品和所有型号为'AC-DIN-CS3'的产品) 问题:我需要基于搜索字符串构建单个查询的帮助(示例1的等式,它将给出与示例1相同的结果)。 因此,这个带有调整的新Equiv查询将满足这两个示例 我还更新了中的模式 提前谢谢你的帮助具有动态搜索条件的SQL搜索查询,sql,sql-server,sql-server-2012,Sql,Sql Server,Sql Server 2012,我有一个旧的动态SQL查询,如下所示,其中where子句中的条件根据搜索文本动态追加 示例1:搜索字符串“AMX AC-DIN-CS3括号” 这里有3个And子句,因为搜索字符串中有3个部分(用空格分隔(AMX、AC-DIN-CSS3和括号) 示例2:搜索字符串“AMX AC-DIN-CS3” 这里有2个And子句,因为搜索字符串中有2个部分(AMX、AC-DIN-CS3) 我想摆脱动态sql,创建一个查询,根据搜索字符串得到与上面相同的结果,但得到的结果不同 与例1相当,但有额外结果 这里我得
注意:
[dbo].[SplitString]
将字符串的distint部分作为表返回。
在这里输入“AMX-AC-DIN-CS3”它将返回
'AMX'
'AC-DIN-CS3'
问题是部分匹配 尝试下面的查询 每个关键字的匹配项都会获得其编号,如果product max number等于关键字总数,则匹配项已满,应选择product
select * from
(
SELECT
DISTINCT Prod.*
,row_number() over
(partition by Pk_ProductID
order by SearchParts.part) as num
FROM Tx_Product Prod
CROSS APPLY (SELECT DISTINCT '%'+part+'%' as part FROM [dbo].[SplitString] (@SearchString,'')) AS SearchParts
Where Fk_CompanyId = 1
AND (ModelNumber LIKE SearchParts.part OR Prod.Manufacturer LIKE SearchParts.part
OR Prod.Category LIKE SearchParts.part OR Prod.[Description] LIKE SearchParts.part)
) T
-- the number of last line for product
-- is equal to total count of keywords
where T.num = (SELECT count(DISTINCT part) FROM [dbo].[SplitString] (@SearchString,''))
问题是部分匹配 尝试下面的查询 每个关键字的匹配项都会获得其编号,如果product max number等于关键字总数,则匹配项已满,应选择product
select * from
(
SELECT
DISTINCT Prod.*
,row_number() over
(partition by Pk_ProductID
order by SearchParts.part) as num
FROM Tx_Product Prod
CROSS APPLY (SELECT DISTINCT '%'+part+'%' as part FROM [dbo].[SplitString] (@SearchString,'')) AS SearchParts
Where Fk_CompanyId = 1
AND (ModelNumber LIKE SearchParts.part OR Prod.Manufacturer LIKE SearchParts.part
OR Prod.Category LIKE SearchParts.part OR Prod.[Description] LIKE SearchParts.part)
) T
-- the number of last line for product
-- is equal to total count of keywords
where T.num = (SELECT count(DISTINCT part) FROM [dbo].[SplitString] (@SearchString,''))
请试试这个:
select *
from Tx_Product prod
where prod.Fk_CompanyId=1
and exists (
select 1
from (
select up.Pk_ProductID, up.Fk_CompanyId, up.attribute, up.value
from (select p.Pk_ProductID, p.Fk_CompanyId
, CONVERT(varchar(max),p.ModelNumber) ModelNumber
, CONVERT(varchar(max),p.Manufacturer) Manufacturer
, CONVERT(varchar(max),p.Category) Category
, CONVERT(varchar(max),p.[Description]) [Description]
from Tx_Product p) p
unpivot (value for attribute in (ModelNumber, Manufacturer, Category, [Description])) up
) p
join [dbo].[SplitString] (@SearchString,'') s on p.value like '%'+s.part+'%'
and p.Pk_ProductID=prod.Pk_ProductID
having COUNT(distinct s.part)=(select COUNT(1) from [dbo].[SplitString] (@SearchString,''))
)
请试试这个:
select *
from Tx_Product prod
where prod.Fk_CompanyId=1
and exists (
select 1
from (
select up.Pk_ProductID, up.Fk_CompanyId, up.attribute, up.value
from (select p.Pk_ProductID, p.Fk_CompanyId
, CONVERT(varchar(max),p.ModelNumber) ModelNumber
, CONVERT(varchar(max),p.Manufacturer) Manufacturer
, CONVERT(varchar(max),p.Category) Category
, CONVERT(varchar(max),p.[Description]) [Description]
from Tx_Product p) p
unpivot (value for attribute in (ModelNumber, Manufacturer, Category, [Description])) up
) p
join [dbo].[SplitString] (@SearchString,'') s on p.value like '%'+s.part+'%'
and p.Pk_ProductID=prod.Pk_ProductID
having COUNT(distinct s.part)=(select COUNT(1) from [dbo].[SplitString] (@SearchString,''))
)
我更喜欢使用CTE使查询文本更具可读性 我假设表
Tx\u Product
有一个主键ID
首先,我们将@SearchString
转换为一个表,然后计算其中的行数以得到关键字的总数
您希望找到具有所有给定关键字的产品
对于每个关键字,我们使用CROSS-APPLY
获取包含该关键字的产品ID列表。然后我们按ID分组以计算匹配数,并仅保留那些具有匹配数的ID与关键字总数相同
最后,我们使用找到的ID从表中获取所有产品详细信息
这是一个基于你的
WITH
CTE_Parts
AS
(
SELECT DISTINCT '%' + part + '%' AS Part
FROM [dbo].[SplitString](@SearchString,'')
)
,CTE_PartCount
AS
(
SELECT COUNT(*) AS PartCount
FROM CTE_Parts
)
,CTE_ProductIDs
AS
(
SELECT
ID
FROM
CTE_Parts
CROSS APPLY
(
SELECT ID
FROM Tx_Product
WHERE
Fk_CompanyId = 1
AND (ModelNumber LIKE CTE_Parts.Part
OR Manufacturer LIKE CTE_Parts.Part
OR Category LIKE CTE_Parts.Part
OR [Description] LIKE CTE_Parts.Part)
) AS CA
GROUP BY ID
HAVING COUNT(*) = (SELECT PartCount FROM CTE_PartCount)
)
SELECT
Tx_Product.*
FROM
CTE_ProductIDs
INNER JOIN Tx_Product ON Tx_Product.ID = CTE_ProductIDs.ID
我更喜欢使用CTE使查询文本更具可读性 我假设表
Tx\u Product
有一个主键ID
首先,我们将@SearchString
转换为一个表,然后计算其中的行数以得到关键字的总数
您希望找到具有所有给定关键字的产品
对于每个关键字,我们使用CROSS-APPLY
获取包含该关键字的产品ID列表。然后我们按ID分组以计算匹配数,并仅保留那些具有匹配数的ID与关键字总数相同
最后,我们使用找到的ID从表中获取所有产品详细信息
这是一个基于你的
WITH
CTE_Parts
AS
(
SELECT DISTINCT '%' + part + '%' AS Part
FROM [dbo].[SplitString](@SearchString,'')
)
,CTE_PartCount
AS
(
SELECT COUNT(*) AS PartCount
FROM CTE_Parts
)
,CTE_ProductIDs
AS
(
SELECT
ID
FROM
CTE_Parts
CROSS APPLY
(
SELECT ID
FROM Tx_Product
WHERE
Fk_CompanyId = 1
AND (ModelNumber LIKE CTE_Parts.Part
OR Manufacturer LIKE CTE_Parts.Part
OR Category LIKE CTE_Parts.Part
OR [Description] LIKE CTE_Parts.Part)
) AS CA
GROUP BY ID
HAVING COUNT(*) = (SELECT PartCount FROM CTE_PartCount)
)
SELECT
Tx_Product.*
FROM
CTE_ProductIDs
INNER JOIN Tx_Product ON Tx_Product.ID = CTE_ProductIDs.ID
你很接近,我有两个产品(在结果集中,制造为'AMX',型号为'AC-DIN-CS3',类别为'括号',但你的答案只得到一条记录。啊,得到了,T.num>(从[dbo].[SplitString](@SearchString,')中选择计数(不同部分))修复了该问题。如果搜索字符串为“AMX”,我应该得到所有制造商为“AMX”的产品,有8个结果,但通过您的查询,我只得到1条记录。@sudhAnsu63,如果您按
行数的一部分进行分区,这会有所帮助。我无法测试。您能创建SQLFIDLE吗?我已经为您添加了FIDLE非常接近,我有2个产品(在结果集中,制造为'AMX',型号为'AC-DIN-CS3',类别为'括号',但您的答案只得到1条记录。啊,得到了,T.num>(从[dbo].[SplitString](@SearchString,')中选择计数(不同部分))修复了该问题。如果搜索字符串为“AMX”,我应该得到所有制造商为“AMX”的产品,有8个结果,但通过您的查询,我只得到1条记录。@sudhAnsu63,如果您按行数的一部分进行分区,这会有所帮助。我无法测试。您能创建SQLFIDLE吗?我已经添加了FIDDLDO您的表Tx\u Product
有一个具有唯一ID
的字段吗?@VladimirBaranov是的,我有一个主键Pk\u productid您的表Tx\u Product
有一个具有唯一ID
的字段吗?@VladimirBaranov是的,我有一个主键Pk\u productid它不工作,返回所有记录。您可以在小提琴中进行检查。有一个关键字有多个匹配项,而另一个关键字没有匹配项。我更正了解决方案。它不起作用,返回所有记录。您可以签入小提琴。一个关键字有多个匹配项,而另一个关键字没有匹配项。我更正了解决方案。