Sql server DRY T-SQL case语句
有没有更干练的方法来写这个案例陈述Sql server DRY T-SQL case语句,sql-server,tsql,sql-server-2012,Sql Server,Tsql,Sql Server 2012,有没有更干练的方法来写这个案例陈述 case when try_convert(int, [MIXED USE FIELD]) >= 0 and try_convert(int, [MIXED USE FIELD]) <= 5 then 1 ... when try_convert(int, [MIXED USE FIELD]) > 20 then 2 else -9 end **编辑** 样本数据: 0 to 2 > 10 6 由于TRY\u CO
case
when try_convert(int, [MIXED USE FIELD]) >= 0 and try_convert(int, [MIXED USE FIELD]) <= 5 then 1
...
when try_convert(int, [MIXED USE FIELD]) > 20 then 2
else -9
end
**编辑**
样本数据:
0 to 2
> 10
6
由于
TRY\u CONVERT
只能处理离散值,因此我不确定子查询是否有用。目前,我正在处理不同代码子分支中的范围值。您可以执行一个子查询以获取try\u convert结果,然后外部查询运行case语句。大概是这样的:
-- use equivalence
SELECT CASE
WHEN s.converted >= 0 AND s.converted < 6 THEN 1
WHEN s.converted >= 6 AND s.converted < 11 THEN 2
WHEN s.converted >= 11 AND s.converted < THEN 3
WHEN s.converted > 20 THEN 4
END calc
FROM (
SELECT converted = try_convert([MIXED_USE_FIELD])
FROM TABLE
) s
...
case
when tc.c between 0 and 5 then 1
when tc.c between 6 and 10 then 2
when tc.c between 11 and 20 then 3
when tc.c > 20 then 4
else -9
end
from ... as a
outer apply (select ry_convert(int, [MIXED USE FIELD]) as tc) as c
你可以这样做:
-- use equivalence
SELECT CASE
WHEN s.converted >= 0 AND s.converted < 6 THEN 1
WHEN s.converted >= 6 AND s.converted < 11 THEN 2
WHEN s.converted >= 11 AND s.converted < THEN 3
WHEN s.converted > 20 THEN 4
END calc
FROM (
SELECT converted = try_convert([MIXED_USE_FIELD])
FROM TABLE
) s
...
case
when tc.c between 0 and 5 then 1
when tc.c between 6 and 10 then 2
when tc.c between 11 and 20 then 3
when tc.c > 20 then 4
else -9
end
from ... as a
outer apply (select ry_convert(int, [MIXED USE FIELD]) as tc) as c
我使用crossapply进行转换,并对case语句使用一些算法。试一试:
DECLARE @Table TABLE ([MIXED USE FIELD] VARCHAR(2));
INSERT INTO @Table
VALUES ('1'),('6'),('15'),('21'),('-1');
SELECT [MIXED USE FIELD],
CASE
WHEN MUF_int BETWEEN 0 AND 20 THEN CEILING(muf_int/5.0)
WHEN MUF_int > 20 THEN 4
ELSE -9
END case_results
FROM @Table
CROSS APPLY (SELECT TRY_CONVERT(INT,[MIXED USE FIELD])) AS CA(MUF_int)
结果:
MIXED USE FIELD case_results
--------------- ---------------------------------------
1 1
6 2
15 3
21 4
-1 -9
在这种情况下,我不会尝试重构。如果您的目标是可读、可维护的代码,那么用一个足够描述性的名称来代替
try\u convert()
将与函数本身一样冗长。没有足够的额外清晰度来证明额外的间接性
SQL不是一种漂亮的语言。不要把口红贴在猪身上。< / P>
select
case
when try_convert(int, [MIXED USE FIELD]) between 0 and 5 then 1
when try_convert(int, [MIXED USE FIELD]) between 6 and 10 then 2
when try_convert(int, [MIXED USE FIELD]) between 11 and 20 then 3
when try_convert(int, [MIXED USE FIELD]) > 20 then 4
else -9
end
from MyTable t1
与:
select
case
when [MIXED USE FIELD as int] between 0 and 5 then 1
when [MIXED USE FIELD as int] between 6 and 10 then 2
when [MIXED USE FIELD as int] between 11 and 20 then 3
when [MIXED USE FIELD as int] > 20 then 4
else -9
end
from MyTable t1
cross apply (
select try_convert(int, [MIXED USE FIELD]) as [MIXED USE FIELD as int]
) t2
另一种方法是用SQL方式重写:将业务规则封装在数据中,而不是代码中。将这些范围移动到表中
CREATE TABLE MyRangeFilterTable (
[RangeFrom] int DEFAULT -2147483648
,[RangeTo] int DEFAULT 2147483647
,[Value] int
)
INSERT MyRangeFilterTable VALUES
( 0, 5, 1)
,( 6, 10, 2)
,(11, 20, 3)
,(20, DEFAULT, 4)
,(NULL, NULL, -9)
SELECT
[Value]
FROM MyTable
INNER JOIN MyRangeFilterTable
ON (TRY_CONVERT(int, [MIXED USE FIELD]) BETWEEN [RangeFrom] AND [RangeTo])
OR (TRY_CONVERT(int, [MIXED USE FIELD]) IS NULL AND [RangeFrom] IS NULL)
现在,您可以在不更改代码的情况下更改规则。您可以使用CTE或派生表来避免try\u转换的重复,但这就是我所能想到的您所能做的。您的唯一问题是,如果记录太多,则加入try\u转换可能会非常慢。我喜欢MyRangeFilterIdea,但是做子查询(或定义函数)可能比连接更好。