SQL Server 当筛选器是逗号分隔的值列表时如何筛选记录

z9zf31ra  于 2022-12-28  发布在  其他
关注(0)|答案(5)|浏览(210)

我有一个表,其中有一列包含逗号分隔值(CSV)字符串。
例如,值1、值2、值3
作为过滤器传入的是另一组CSV。
例如,值2、值3
因此,在上面的示例中,查询应该返回CSV列中包含任何筛选器值的任何记录。

    • 示例**
declare @table table
(
    rownum int,
    csv nvarchar(300)
)

insert into @table values (1,'VALUE1, VALUE2, VALUE3')
insert into @table values (2,'VALUE1, VALUE2')
insert into @table values (3,'VALUE1, VALUE3')
insert into @table values (4,'VALUE3, VALUE4')
insert into @table values (5,'VALUE1, VALUE2, VALUE3')
insert into @table values (6,'VALUE3, VALUE4, VALUE2')
insert into @table values (7,'VALUE3')

declare @Filter nvarchar(50)

set @Filter = 'VALUE1,VALUE2'

select * from @table

因此,在上面的示例中,查询应该返回行1、2、3、5和6,因为它们都包含VALUE1或VALUE2。

ffscu2ro

ffscu2ro1#

如果我能很好地理解它,这将解决它:
创建一个函数来执行拆分:

CREATE FUNCTION [dbo].[ufn_CSVToTable] ( @StringInput VARCHAR(8000), @Delimiter nvarchar(1))
RETURNS @OutputTable TABLE ( [String] VARCHAR(10) )
AS
BEGIN

    DECLARE @String    VARCHAR(10)

    WHILE LEN(@StringInput) > 0
    BEGIN
        SET @String      = LEFT(@StringInput, 
                                ISNULL(NULLIF(CHARINDEX(@Delimiter, @StringInput) - 1, -1),
                                LEN(@StringInput)))
        SET @StringInput = SUBSTRING(@StringInput,
                                     ISNULL(NULLIF(CHARINDEX(@Delimiter, @StringInput), 0),
                                     LEN(@StringInput)) + 1, LEN(@StringInput))

        INSERT INTO @OutputTable ( [String] )
        VALUES ( @String )
    END

    RETURN
END
GO

然后您可以执行以下操作:

declare @table table
(
    rownum int,
    csv nvarchar(300)
)

insert into @table values (1,'VALUE1, VALUE2, VALUE3')
insert into @table values (2,'VALUE1, VALUE2')
insert into @table values (3,'VALUE1, VALUE3')
insert into @table values (4,'VALUE2, VALUE3')
insert into @table values (5,'VALUE1, VALUE2, VALUE3')
insert into @table values (6,'VALUE3, VALUE1, VALUE2')
insert into @table values (7,'VALUE2, VALUE1')

declare @Filter nvarchar(50)

set @Filter = 'VALUE3,VALUE4'

select * from @table
SELECT * INTO #FilterTable FROM ufn_CSVToTable(@Filter, ',')
SELECT * FROM #FilterTable
select * from @table where EXISTS(SELECT String FROM #FilterTable WHERE csv like '%' + String + '%')
DROP TABLE #FilterTable

我正在考虑“返回包含过滤器中任何calue的任何rown”的描述

anauzrmj

anauzrmj2#

您可以使用PatIndex来找出字段中的模式。如下所示:

SELECT * FROM @TABLE WHERE PATINDEX('%'+@FILTER+'%',CSV)>0
bttbmeg0

bttbmeg03#

现在呢?我根本没有使用任何用户定义的函数。

declare @table table
(
    rownum int,
    csv nvarchar(300)
)

insert into @table values (1,'VALUE1,VALUE2,VALUE3')
insert into @table values (2,'VALUE1,VALUE2')
insert into @table values (3,'VALUE1,VALUE3')
insert into @table values (4,'VALUE2,VALUE3')
insert into @table values (5,'VALUE1,VALUE2,VALUE3')
insert into @table values (6,'VALUE3,VALUE1,VALUE2')
insert into @table values (7,'VALUE2,VALUE1')

DECLARE @FILTER VARCHAR(50)
DECLARE @IN VARCHAR(MAX)
SET @FILTER='VALUE1,VALUE2'
SET @IN=REPLACE(@FILTER,',','%')
SET @IN='%'+@IN+'%'
SELECT @IN
SELECT * FROM @table WHERE PATINDEX(@IN,RTRIM(LTRIM(CSV))) >0
6ie5vjzr

6ie5vjzr4#

试试这个-

DECLARE @table TABLE (rownum INT, csv NVARCHAR(300))

INSERT INTO @table 
VALUES 
       (1,'VALUE1, VALUE2, VALUE3')
     , (2,'VALUE1, VALUE2')
     , (3,'VALUE1, VALUE3')
     , (4,'VALUE2, VALUE3')
     , (5,'VALUE1, VALUE2, VALUE3')
     , (6,'VALUE3, VALUE1, VALUE2')
     , (7,'VALUE2, VALUE1')

DECLARE @Filter NVARCHAR(50)
SELECT @Filter = 'VALUE1,VALUE2'

;WITH cte AS 
(
     SELECT token = SUBSTRING(
          t.string
        , n.number + 1
        , ABS(CHARINDEX(',', t.string, n.number + 1) - n.number - 1))
     FROM ( SELECT string = ',' + @Filter ) t
     CROSS JOIN [master].dbo.spt_values n
     WHERE n.[type] = 'p'
         AND n.number <= LEN(t.string)
         AND SUBSTRING(t.string, n.number, 1) = ','
)
SELECT DISTINCT rownum, csv
FROM cte
JOIN @table ON PATINDEX('%'+ token +'%', CSV) = 0
hwazgwia

hwazgwia5#

我刚刚使用STRING_SPLIT函数修改了@JoseTeixeira代码。

declare @table table
(
    rownum int,
    csv nvarchar(300)
)

insert into @table values (1,'VALUE1, VALUE2, VALUE3')
insert into @table values (2,'VALUE1, VALUE2')
insert into @table values (3,'VALUE1, VALUE3')
insert into @table values (4,'VALUE2, VALUE3')
insert into @table values (5,'VALUE1, VALUE2, VALUE3')
insert into @table values (6,'VALUE3, VALUE1, VALUE2')
insert into @table values (7,'VALUE2, VALUE1')

declare @Filter nvarchar(50)

set @Filter = 'VALUE3,VALUE4'

--select * from @table
select * from @table where EXISTS(SELECT [value] FROM string_split(@Filter, ',')
WHERE csv like '%' + [value] + '%') -- Table with filtered records

相关问题