case when vh.km<=7500 then 5000
when vh.km>7500 and vh.km<=12500 then 10000
when vh.km>12500 and vh.km<=17500 then 15000
when vh.km>17500 and vh.km<=22500 then 20000
when vh.km>22500 and vh.km<=27500 then 25000
when vh.km>27500 and vh.km<=32500 then 30000
when vh.km>32500 and vh.km<=37500 then 35000
when vh.km>37500 and vh.km<=42500 then 40000
when vh.km>42500 and vh.km<=47500 then 45000
.................
如您所见,它增加了5000,周期很长,那么我想知道它是否可以简化,希望您能帮助我
答案 0 :(得分:8)
只有vh.km
是整数,才可以使用简单的数学运算。
SELECT (((vh.km-2501)/5000) + 1)*5000
除非您未提及任何内容,否则这似乎遵循以下测试所指示的模式。
WITH
E(n) AS(
SELECT n FROM (VALUES(0),(0),(0),(0),(0),(0),(0),(0),(0),(0))E(n)
),
E2(n) AS(
SELECT a.n FROM E a, E b
),
E4(n) AS(
SELECT a.n FROM E2 a, E2 b
),
cteTally(km) AS(
SELECT ROW_NUMBER() OVER(ORDER BY (SELECT NULL)) * 100 n
FROM E4
)
SELECT km,
case when vh.km<=7500 then 5000
when vh.km>7500 and vh.km<=12500 then 10000
when vh.km>12500 and vh.km<=17500 then 15000
when vh.km>17500 and vh.km<=22500 then 20000
when vh.km>22500 and vh.km<=27500 then 25000
when vh.km>27500 and vh.km<=32500 then 30000
when vh.km>32500 and vh.km<=37500 then 35000
when vh.km>37500 and vh.km<=42500 then 40000
when vh.km>42500 and vh.km<=47500 then 45000
END,
(((vh.km-2501)/5000) + 1)*5000
FROM cteTally vh
答案 1 :(得分:0)
类似的事情也可以,对于0情况只需要一个简单的CASE
表达式。这也使您可以使用一个简单的变量来驱动上限/循环,而不必定义所有范围。实际上,这只是一个复杂的问题,因为除了第一个范围之外,所有范围/结果都是统一的。
DECLARE @numCycles tinyint = 10;
;WITH x AS
(
SELECT n = 1 UNION ALL SELECT n+1 FROM x WHERE n < @numCycles
), y AS
(
SELECT s = 7500 + ((n-2)*5000)-CASE n WHEN 1 THEN 2501 ELSE 0 END,
e = 7500 + ((n-1)*5000),
r = n*5000
FROM x
)
SELECT vh.km, y.r /* , vh.<othercols> */
FROM y INNER JOIN dbo.table_name AS vh
ON vh.km > y.s AND vh.km <= y.e;
如果周期超过100,则需要添加OPTION (MAXRECURSION n)
:
-- if @numCycles > 100 and < 32768:
-- OPTION (MAXRECURSION <numCycles>);
-- if @numCycles >= 32768
-- OPTION (MAXRECURSION 0);
如果循环数超过255,则需要更改tinyint
,否则所有操作仍将相同。