有一种方法可以从数据库中减少这种情况

时间:2019-03-04 22:02:39

标签: sql-server

 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,周期很长,那么我想知道它是否可以简化,希望您能帮助我

2 个答案:

答案 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,否则所有操作仍将相同。