假设我们有一张桌子。 此表具有每个学生代码的列(varchar)。 我想根据我设置的过滤器搜索许多学生。
例如,我有一个用户插入的问题字段(varchar)
用逗号分隔的代码,例如000012,000014,000058
。
问题字段会返回'000012,000014,000058'
之类的值
SQL查询以这种方式实现问题字段
Select * from Students where code in ( '000012,000014,000058')
我必须将值更改为:('000012','000014','000058')
所以使用替换函数REPLACE(CHAR(39)+'000012,000014,000058'+CHAR(39),',',CHAR(39)+','+CHAR(39))
我正在尝试这个
Select *
from students
where code in (REPLACE(CHAR(39)+'000012,000014,000058'+CHAR(39),',',CHAR(39)+','+CHAR(39)))
但仍然没有工作。
任何想法?
答案 0 :(得分:1)
你的REPLACE(...
会返回一个字符串,你需要的是类似于桌子的东西。将字符串(varchar)拆分为表有很多方法。这只是其中之一。
declare @ids varchar(100)='000012,000014,000058'
declare @x xml='<x>'+replace(@ids,',','</x><x>')+'</x>'
select * from students
where code in (
select t.x.value('.[1]','varchar(10)')
from @x.nodes('x') t(x)
)
答案 1 :(得分:0)
正如jpw所说,在单元格中使用逗号分隔的值会违反第一范式,因此SQL的查询能力已被破坏。在这种情况下你可以做的是先恢复正常状态,然后照常进行:
如果您有SQL Server 2016,可以使用带有交叉应用的string_split将单元格拆分回行(here's a backwards compatible string_split for earlier versions),例如:
select s.* from students s cross apply string_split(code, ',')
where value in ('000012','000014','000058')
..或者,如果您没有2016并且不想添加string_split功能,您可以像在Alex的答案中一样使用.nodes:
select s.* from students s cross apply
(select convert(xml, '<x>' + replace(code, ',', '</x><x>') + '</x>')) a(code_xml)
cross apply code_xml.nodes('*') x(n)
where n.value('.','varchar(20)') in ('000012','000014','000058')
---编辑---
您在评论中注意到,您声明数据库单元格不包含逗号分隔值 - 在这种情况下,Alex的回答是合适的。