我有一个表,其中有一列包含一串逗号分隔值(CSV)。
e.g。 VALUE1,VALUE2,VALUE3
作为过滤器传入是另一组CSV。
e.g。 VALUE2,VALUE3
因此,在上面的示例中,查询应返回任何过滤值在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。
答案 0 :(得分:4)
如果我理解它,这将解决它:
您创建了一个执行拆分的功能:
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
我正在考虑描述“返回包含过滤器中任何卡片的任何rown”
答案 1 :(得分:0)
您可以使用PatIndex查找字段中的模式。如下:
SELECT * FROM @TABLE WHERE PATINDEX('%'+@FILTER+'%',CSV)>0
答案 2 :(得分:0)
试试这个 -
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
答案 3 :(得分:0)
现在怎么样?我根本没有使用任何用户定义的函数。
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