代码之家  ›  专栏  ›  技术社区  ›  Fortega

在case子句中循环表达式时为sql case

  •  1
  • Fortega  · 技术社区  · 15 年前

    我的疑问是:

    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。

    2 回复  |  直到 15 年前
        1
  •  1
  •   davek    15 年前

    不知道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
    
        2
  •  0
  •   outis    15 年前

    您还可以尝试存储函数。类似:

    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 .