2009-12-14 41 views
1

我的查询:SQL CASE WHEN的情况下,第周期性表达

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(DIGITS(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 ... 

你可以看到下面的部分被多次复制

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) 

是否有可能有这个只有一次?如果是这样,怎么样?这会对性能产生影响吗?谢谢!数据库是DB2。

+0

列STOCK_MONTH的类型是什么? – outis 2009-12-14 15:45:03

回答

1

不知道关于DB2,但我会尝试这个办法:

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 
0

你也可以尝试存储功能。例如:

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) 

上述内容未在DB2上进行测试;你的里程和语法可能有所不同。随意重新命名这些功能(无可否认),并将任务分解为您认为合适的任何功能。 daysdiff可能可以改进,这取决于STOCK_MONTH的类型。