我们有一个非常宽的表,其中包含25个诊断代码列:
XTemplate
如果我要查找诊断代码'12345',我需要写
diag1, diag2, … diag25.
有没有办法做这样的事情:
diag1 ='12345' or diag2='12345' or diag3='12345'... or diag25='12345'
答案 0 :(得分:4)
你可以写
'12345' IN (diag1, diag2, ..., diag25)
但是diag1-diag25没有语法
答案 1 :(得分:3)
您可以将XML的通用功能称为抢救。可能行数不是很快,但是非常强大:
(向iamdave致谢)
declare @t table(id int,diag1 int,diag2 int,diag3 int,diag4 int,diag5 int,diag6 int,diag7 int,diag8 int,diag9 int,diag10 int);
insert into @t (id, diag5) values(1,12345);
insert into @t (id, diag3) values(2,123);
insert into @t (id, diag8, diag1) values(3,123,12345);
insert into @t (id, diag9, diag2) values(4,345,678);
WITH CreateXML AS
(
SELECT *
,(
SELECT *
FROM @t t2
WHERE t1.id=t2.id
FOR XML PATH('codes'),TYPE
).query('/codes/*[substring(local-name(),1,4)="diag"]') AllCodes
FROM @t t1
)
SELECT *
FROM CreateXML
WHERE AllCodes.exist('/*[. cast as xs:int? >=12345 and . cast as xs:int? <=12349]')=1;
查询将使用SELECT *
创建所有列的XML。 .query()
将选择以"diag"
开头的所有元素。也许您必须对此进行调整以适应您的需求。
.exist()
将检查这些元素内的任何值是否在边界之间。一场比赛就足够了。
祝你好运!
答案 2 :(得分:2)
另一种可能更灵活的解决方案是使用cross apply
取消数据透视:
declare @t table(id int,diag1 int,diag2 int,diag3 int,diag4 int,diag5 int,diag6 int,diag7 int,diag8 int,diag9 int,diag10 int);
insert into @t (id, diag5) values(1,12345);
insert into @t (id, diag3) values(2,123);
insert into @t (id, diag8, diag1) values(3,123,12345);
insert into @t (id, diag9, diag2) values(4,345,678);
select t.id
,d.d
from @t as t
cross apply(values(diag1),(diag2),(diag3),(diag4),(diag5),(diag6),(diag7),(diag8),(diag9),(diag10)) d(d)
where d.d = 12345;
输出:
+----+-------+
| id | d |
+----+-------+
| 1 | 12345 |
| 3 | 12345 |
+----+-------+
答案 3 :(得分:1)
实际上,所有这些diagxx
列都应位于单独的表中。因此,您的设计应进行更改。
如果您无法执行此操作,则可以在where子句中使用IN
,从而使查询更加轻松。
declare @d table (diag1 varchar(5), diag2 varchar(5), diag3 varchar(5))
insert into @d values ('12345', '23456', '34567'),
('45678', '12345', '56789'),
('45678', '85236', '56789')
select *
from @d
where '12345' in (diag1, diag2, diag3)
这将返回
diag1 diag2 diag3
----- ----- -----
12345 23456 34567
45678 12345 56789
这与您将要获得的语法非常接近
答案 4 :(得分:1)
另一种方法是将诊断代码UNPIVOT
放在一列中,然后查询结果数据集。
有关取消固定选项的完整讨论,请参阅此问题。 SQL Server : Columns to Rows
使用varchar
诊断代码,BETWEEN
可能无法达到您想要的方式,但是您可以将70多种代码转储到临时表中并加入它。
但是遵循这些原则:
select * from
(
select
<Any Key Fields You Want To Include>,
diagColumnName,
diagCode
from yourtable
unpivot
(
diagCode
for diagColumnName in (diag1, diag2....diag25)
) as unpiv
) as resultSet
join #tempCodes as t
on t.diagCode = resultSet.diagCode
编辑:根据评论添加了联接/临时表。