Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/73.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变量的WHERE in子句在SQL中搜索包括范围在内的值列表?_Sql_Sql Server_Tsql - Fatal编程技术网

使用带有SQL变量的WHERE in子句在SQL中搜索包括范围在内的值列表?

使用带有SQL变量的WHERE in子句在SQL中搜索包括范围在内的值列表?,sql,sql-server,tsql,Sql,Sql Server,Tsql,我试图用SQL变量中的值列表(包括范围)实现搜索功能。感谢任何指向正确方法的指导/链接 以下是数据集: CREATE TABLE [dbo].[Books] ( [ID] [NCHAR](10) NOT NULL, [AUTHCODE] [NCHAR](10) NULL, [TITLE] [NCHAR](10) NULL ) ON [PRIMARY] GO INSERT [dbo].[Books] ([ID], [AUTHCODE], [TITLE]) VALUES

我试图用SQL变量中的值列表(包括范围)实现搜索功能。感谢任何指向正确方法的指导/链接

以下是数据集:

CREATE TABLE [dbo].[Books]
(
    [ID] [NCHAR](10) NOT NULL,
    [AUTHCODE] [NCHAR](10) NULL,
    [TITLE] [NCHAR](10) NULL
) ON [PRIMARY]
GO

INSERT [dbo].[Books] ([ID], [AUTHCODE], [TITLE]) 
VALUES (N'1', N'nk', N'Book1'), 
       (N'2', N'an', N'Book2'),
       (N'3', N'mn', N'Book3'),
       (N'4', N'ra', N'Book4'),
       (N'5', N'kd', N'Book5'),
       (N'6', N'nk', N'Book6'),
       (N'7', N'an', N'Book7'),
       (N'8', N'ra', N'Book8'),
       (N'9', N'kd', N'Book9'),
       (N'10', N'mn', N'Book10    ')
GO
下面我尝试使用SQLIN子句进行筛选,但这不会返回所需的结果

select * from books

declare @List1 varchar(max) = '2,4,6,7,8,9' --simple list

select * 
from books
where id in (@List1)

declare @List2 varchar(max) = '2,4-7,9' --list with range

select * 
from books
where id in (@List2)

不能直接将字符串用作列表,但如果确实需要将筛选参数作为字符串传递,则可以使用:

declare @list varchar(max) = '2,4,6-8,9'
declare @filter table (id1 int, id2 int)

insert into @filter (id1,id2)
select
    case when b.pos > 0 then left(a.[value], pos - 1) else a.[value] end as id1,
    case when b.pos > 0 then right(a.[value], len(a.[value]) - pos) else a.[value] end as id2
from string_split(@list, ',') as a
    cross apply (select charindex('-', a.[value]) as pos) as b

select *
from [dbo].[Books] as b
where
    exists (select * from @filter as tt where b.id between tt.id1 and tt.id2)
另外,可以将过滤器作为json传递,这样可以简化解析部分:

declare @list varchar(max) = '[2,4,[6,8],9]'

select
    case when a.[type] = 4 then json_value(a.[value], '$[0]') else a.[value] end,
    case when a.[type] = 4 then json_value(a.[value], '$[1]') else a.[value] end
from openjson(@list) as a
当然,以上所有内容仅适用于Sql Server 2016或更高版本

运算符确定指定值是否与子查询或列表中的任何值匹配。不是一根绳子,这就是你正在做的

你想做的事可以按你的意愿去做

DECLARE @List1 AS TABLE (ID INT); 

INSERT INTO @List1 
SELECT 2 UNION SELECT 4 UNION SELECT 6 UNION
SELECT 7 UNION SELECT 8 UNION SELECT 9;

SELECT *
FROM Books
WHERE ID IN (SELECT ID FROM @List1);

DECLARE @List2 As TABLE (AFrom INT, ATo INT);

INSERT INTO @List2
SELECT 2, 4 UNION SELECT 7, 9;

SELECT *
FROM Books B CROSS APPLY @List2 L
WHERE B.ID BETWEEN L.AFrom AND L.ATo;

提示:
将@List1声明为表(id int)。在mssql的最新版本中有一个split_string(srring_split)函数。这可能会让你朝着正确的方向前进。Sql in()接受多个参数,varhar()只可能是一个字符串的可能副本