Tsql 跨多个价格范围搜索

Tsql 跨多个价格范围搜索,tsql,sql-server-2017,Tsql,Sql Server 2017,我们最近将一个旧的存储过程从动态SQL转换为直接SQL。这是一个搜索引擎,我们让用户输入字符串值 因此,他们可能希望搜索多个订单号,以便输入 111,222-3,444-0 我们将把该字符串处理为表值中的行,然后将该表连接到主orders表以返回行 问题是,他们的一个选择是在多个价格范围内搜索。因此,他们将选择“发票总额”选项并输入 10-25,100-125,200-300 他们要求的是退回发票总额在10美元到25美元之间、100美元到125美元之间或200美元到300美元之间的订单 我不

我们最近将一个旧的存储过程从动态SQL转换为直接SQL。这是一个搜索引擎,我们让用户输入字符串值

因此,他们可能希望搜索多个订单号,以便输入

111,222-3,444-0
我们将把该字符串处理为表值中的行,然后将该表连接到主orders表以返回行

问题是,他们的一个选择是在多个价格范围内搜索。因此,他们将选择“发票总额”选项并输入

10-25,100-125,200-300
他们要求的是退回发票总额在10美元到25美元之间、100美元到125美元之间或200美元到300美元之间的订单

我不知道该怎么办。当他们搜索字符串文本时,我们只需将列表解析为变形语句的形式,然后将其传递到对FTI的CONTAINSTABLE调用中

你有什么建议吗

10-25,100-125,200-300


或者,在不使用动态SQL的情况下使用功能类似的工具。

您可以使用交叉应用和SQL server sting splitter函数的组合,根据用户的条件筛选数据。以下示例演示了该概念:

DECLARE @filter NVARCHAR(1000) = '10-25,100-125,500,200-300';

;WITH CTE_RangeComparisons
AS
(
    -- Use string split function to get input ranges
    SELECT      [value]
                ,(
                    -- If string contain the ‘-‘ character then we know we have a high limit and low limit specified otherwise we assume a single value.
                    CASE 
                        WHEN CHARINDEX('-',[value])  > 0 THEN CAST(LEFT([value], (CHARINDEX('-',[value]) - 1)) AS FLOAT) 
                        ELSE CAST([value] AS FLOAT)
                    END
                 ) AS LowRange
                ,(
                    CASE 
                        WHEN CHARINDEX('-',[value])  > 0 THEN CAST(RIGHT([value], LEN([value]) - (CHARINDEX('-',[value]))) AS FLOAT)
                        ELSE CAST([value] AS FLOAT)
                    END
                ) AS HighRange
    FROM        string_split(@filter, ',')
)
SELECT      D.*
FROM        [YourDataTable] D
CROSS APPLY (
                -- Use cross apply to filter data on the ranges identified.
                SELECT  1 [Match] -- Selected values here does not matter we are only interested in filtering the parent table.
                FROM    CTE_RangeComparisons R
                WHERE   D.InvoiceTotal >= R.LowRange AND D.InvoiceTotal <= R.HighRange
            ) Ranges

可能最容易重新设计用户界面以提供多个输入字段,而不是强制后端支持各种输入。不幸的是,可以使用两个字符串拆分函数来完成,而不是内置函数,因为您需要在第二次拆分时保留顺序,但我认为更简单的方法是使用动态SQL,或者如果可能的话,更改存储过程以接受具有包含From和to列的行的表值参数。
DECLARE @filter NVARCHAR(1000) = '10-25,100-125,500,200-300';

;WITH CTE_RangeComparisons
AS
(
    -- Use string split function to get input ranges
    SELECT      [value]
                ,(
                    -- If string contain the ‘-‘ character then we know we have a high limit and low limit specified otherwise we assume a single value.
                    CASE 
                        WHEN CHARINDEX('-',[value])  > 0 THEN CAST(LEFT([value], (CHARINDEX('-',[value]) - 1)) AS FLOAT) 
                        ELSE CAST([value] AS FLOAT)
                    END
                 ) AS LowRange
                ,(
                    CASE 
                        WHEN CHARINDEX('-',[value])  > 0 THEN CAST(RIGHT([value], LEN([value]) - (CHARINDEX('-',[value]))) AS FLOAT)
                        ELSE CAST([value] AS FLOAT)
                    END
                ) AS HighRange
    FROM        string_split(@filter, ',')
)
SELECT      D.*
FROM        [YourDataTable] D
CROSS APPLY (
                -- Use cross apply to filter data on the ranges identified.
                SELECT  1 [Match] -- Selected values here does not matter we are only interested in filtering the parent table.
                FROM    CTE_RangeComparisons R
                WHERE   D.InvoiceTotal >= R.LowRange AND D.InvoiceTotal <= R.HighRange
            ) Ranges