Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/68.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
具有动态搜索条件的SQL搜索查询_Sql_Sql Server_Sql Server 2012 - Fatal编程技术网

具有动态搜索条件的SQL搜索查询

具有动态搜索条件的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相当,但有额外结果 这里我得

我有一个旧的动态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查询将满足这两个示例

我还更新了中的模式

提前谢谢你的帮助


注意:
[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它不工作,返回所有记录。您可以在小提琴中进行检查。有一个关键字有多个匹配项,而另一个关键字没有匹配项。我更正了解决方案。它不起作用,返回所有记录。您可以签入小提琴。一个关键字有多个匹配项,而另一个关键字没有匹配项。我更正了解决方案。