2009-12-14 3 views
1

ma requête:CAS SQL QUAND Récurrent expression en cas clause

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

vous pouvez voir les pièces suivantes sont copiées plusieurs fois

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) 

Est-il possible d'avoir qu'une seule fois? Si c'est le cas, comment? Cela aura-t-il un impact sur les performances? Merci! La base de données est DB2.

+0

Quel est le type de colonne STOCK_MONTH? – outis

Répondre

1

Aucune idée de DB2, mais je voudrais essayer ceci:

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

Vous pouvez également essayer les fonctions stockées. Quelque chose comme:

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) 

Ce qui précède n'a pas été testé sur DB2; votre kilométrage et votre syntaxe peuvent varier. N'hésitez pas à renommer les fonctions (qui sont certes mauvaises) et à répartir les tâches dans toutes les fonctions qui vous conviennent. daysdiff pourrait probablement être améliorée, en fonction du type de STOCK_MONTH.