是否有DRYer方式来编写此案例陈述?
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
这种语法不起作用:
case try_convert(int, [MIXED USE FIELD])
when between 0 and 5 then 1
when between 6 and 10 then 2
when between 11 and 20 then 3
when > 20 then 4
else -9
end
**编辑**
示例数据:
0 to 2
> 10
6
由于TRY_CONVERT
仅适用于离散值,因此我不确定子查询是否有用。目前,我在不同的代码子分支中处理范围值。
答案 0 :(得分:3)
您可以执行获取try_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
-- use BETWEEN
SELECT CASE
WHEN s.converted BETWEEN 0 AND 5 THEN 1
WHEN s.converted BETWEEN 6 AND 9 THEN 2
WHEN s.converted BETWEEN 11 AND 20 THEN 3
WHEN s.converted > 20 THEN 0
END calc
FROM (
SELECT converted = try_convert([MIXED_USE_FIELD])
FROM TABLE
) s
答案 1 :(得分:2)
object(stdClass)[4]
public 'lib' =>
object(stdClass)[3]
public 'test' =>
object(stdClass)[2]
public 'test2' =>
object(stdClass)[1]
...
object(stdClass)[3]
public 'test' =>
object(stdClass)[2]
public 'test2' =>
object(stdClass)[1]
array (size=2)
0 => string 'test' (length=4)
1 => string 'test2' (length=5)
object(stdClass)[4]
public 'lib' =>
object(stdClass)[3]
public 'test' => &
object(stdClass)[2]
Notice: Undefined property: stdClass::$test2
答案 2 :(得分:1)
在这种情况下,我不会尝试重构。如果您的目标是可读的,可维护的代码,那么代替try_convert()
的足够描述性的名称将与函数本身一样冗长。没有足够的额外清晰度来证明额外的间接性。
SQL不是一种漂亮的语言。不要试着把口红涂在猪身上。
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)
现在您可以在不更改代码的情况下更改规则。
答案 3 :(得分:0)
我使用CROSS APPLY进行转换,并使用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