我有一个旧的动态SQL查询,如下所示,where子句中的条件是根据搜索文本动态追加的。
示例1 :搜索字符串' AMX AC-DIN-CS3支架'
SELECT * FROM Tx_Product
Where Fk_CompanyId=1
and (ModelNumber like '%AMX%' or Manufacturer like '%AMX%' or Category like '%AMX%' or [Description] like '%AMX%')
and (ModelNumber like '%AC-DIN-CS3%' or Manufacturer like '%AC-DIN-CS3%' or Category like '%AC-DIN-CS3%' or [Description] like '%AC-DIN-CS3%')
and (ModelNumber like '%Bracket%' or Manufacturer like '%Bracket%' or Category like '%Bracket%' or [Description] like '%Bracket%')
这里有3个And子句,因为搜索字符串中有3个部分(以空格分隔(AMX,AC-DIN-CSS3和Bracket)。
示例2 :搜索字符串' AMX AC-DIN-CS3'
SELECT * FROM Tx_Product
Where Fk_CompanyId=1
and (ModelNumber like '%AMX%' or Manufacturer like '%AMX%' or Category like '%AMX%' or [Description] like '%AMX%')
and (ModelNumber like '%AC-DIN-CS3%' or Manufacturer like '%AC-DIN-CS3%' or Category like '%AC-DIN-CS3%' or [Description] like '%AC-DIN-CS3%')
这里有2个和子句,因为搜索字符串中有2个部分(AMX,AC-DIN-CS3)。
我想摆脱动态sql 并创建一个单独的查询,根据搜索字符串得到与上面相同的结果,但我得到的结果不同。
相当于示例1 但是有额外的结果
DECLARE @SearchString NVARCHAR(MAX) = 'AMX AC-DIN-CS3 Bracket'
SELECT DISTINCT Prod.* FROM Tx_Product Prod
CROSS APPLY (SELECT DISTINCT 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)
在这里,我得到额外的记录,如(所有产品与制造商' AMX' 以及所有产品与ModelNumber ' AC-DIN-CS3&# 39; )
问题我希望根据搜索字符串帮助构建单个查询(示例1的等式,这将给出与示例1相同的结果)。 因此,这个带有调整的新Equiv查询将满足这两个示例。
我已更新SQL Fidddle中的架构。
先谢谢你的帮助。
注意: [dbo].[SplitString]
以字符串形式返回字符串的distint部分。
这里'AMX-AC-DIN-CS3'
将返回
'AMX'
'AC-DIN-CS3'
答案 0 :(得分:3)
问题是部分匹配。
尝试以下查询。
每个关键字的匹配都会获得其编号,如果产品最大数量等于关键字的总数,则匹配已满并且应选择产品
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,''))
答案 1 :(得分:2)
我更喜欢使用CTE来使查询文本更具可读性。
我认为表Tx_Product
有一个主键ID
。
首先我们将@SearchString
转换为表格。然后计算其中的行数以获得关键字的总数。
您希望找到包含所有给定关键字的产品。
对于每个关键字,我们使用CROSS APPLY
来获取包含此关键字的产品ID列表。然后我们按ID分组以计算匹配数,并仅保留匹配数与关键字总数相同的ID。
最后,我们使用找到的ID从表中获取所有产品详细信息。
以下是基于您的SQL Fiddle。
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
答案 2 :(得分:1)
请试试这个:
$(".preview-audio").insertAfter($(".foo"));