开发者

SQL CASE WHEN Recurring expression in case clause

my query:

SELECT
CASE 
WHEN 
DAYS(DATE(
SUBSTR(DIGITS(STOCK_MONTH),5,4)  CONCAT '-'  CONCAT
SUBSTR(DIGITS(STOCK_MONTH),9,2)  CONCAT '-01') - 1 DAY + 1 MONTH)
- DAYS(HUB_ARRIVAL_DT) < 31 THEN ' 030'
WHEN 
DAYS(DATE(
SUBSTR(DIGITS(STOCK_MONTH),5,4)  CONCAT '-'  CONCAT
SUBSTR(DIGITS(STOCK_MONTH),9,2)  CONCAT '-01') - 1 DAY + 1 MONTH)
- DAYS(HUB_ARRIVAL_DT) < 61 THEN ' 060'
WHEN 
DAYS(DATE(
SUBSTR(DIGITS(STOCK_MONTH),5,4)  CONCAT '-'  CONCAT
SUBSTR(DIGITS(STOCK_MONTH),9,2)  CONCAT '-01') - 1 DAY + 1 MONTH)
- DAYS(HUB_ARRIVAL_DT) < 91 THEN ' 090'
WHEN 
DAYS(DATE(
SUBSTR(D开发者_JAVA百科IGITS(STOCK_MONTH),5,4)  CONCAT '-'  CONCAT
SUBSTR(DIGITS(STOCK_MONTH),9,2)  CONCAT '-01') - 1 DAY + 1 MONTH)
- DAYS(HUB_ARRIVAL_DT) < 181 THEN ' 180'
ELSE '>180'
END AS AGED
FROM ...

you can see the following parts is copied several times

DAYS(DATE(
SUBSTR(DIGITS(STOCK_MONTH),5,4)  CONCAT '-'  CONCAT
SUBSTR(DIGITS(STOCK_MONTH),9,2)  CONCAT '-01') - 1 DAY + 1 MONTH)
- DAYS(HUB_ARRIVAL_DT)

Is it possible to have this only once? If so, how? Will this have a performance impact? Thanks! Database is DB2.


No idea about DB2, but I would try this:

select
  CASE 
  WHEN 
  computed_col < 31 THEN ' 030'
  ...
  END AS AGED
from
(
  select DAYS(DATE(
  SUBSTR(DIGITS(STOCK_MONTH),5,4)  CONCAT '-'  CONCAT
  SUBSTR(DIGITS(STOCK_MONTH),9,2)  CONCAT '-01') - 1 DAY + 1 MONTH)
  - DAYS(HUB_ARRIVAL_DT) as computed_col
  from...
) as x


You could also try stored functions. Something like:

CREATE FUNCTION daysdiff (
    "start" INT, 
    "end" DATE
) RETURNS INT
  DETERMINISTIC NO EXTERNAL ACTION
  RETURN DAYS(DATE(
              SUBSTR(DIGITS(daysdiff."start"),5,4)  CONCAT '-'  CONCAT
              SUBSTR(DIGITS(daysdiff."start"),9,2)  CONCAT '-01') - 1 DAY + 1 MONTH)
         - DAYS(daysdiff."end")

CREATE FUNCTION monthly (
   "days" INT
) RETURNS INT
  DETERMINISTIC NO EXTERNAL ACTION
  RETURN CEILING(monthly."days" / 30) * 30

CREATE FUNCTION daystr ("days" INT, "max" INT)
  RETURNS char(4)
  DETERMINISTIC NO EXTERNAL ACTION
  RETURN
    CASE WHEN daystr."days" <= daystr."max" THEN
        CHAR(DECIMAL(daystr."days", INT(LOG10(daystr."max"))+1, 0))
    ELSE '>' CONCAT CHAR(DECIMAL(daystr."max", INT(LOG10(daystr."max"))+1, 0))
    END

CREATE FUNCTION monthlydiffstr (
    "start" INT, 
    "end" DATE
) RETURNS INT
  RETURN daystr(monthly(daysdiff(monthlydiffstr."start", monthlydiffstr."end")), 180)

The above was not tested on DB2; your mileage and syntax may vary. Feel free to rename the functions (which are admittedly bad) and break down the tasks into whatever functions you see fit. daysdiff could probably be improved, depending on the type of STOCK_MONTH.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜