【问题标题】:Nested SELECT and CASE statements within same table在同一个表中嵌套 SELECT 和 CASE 语句
【发布时间】:2019-05-06 03:32:56
【问题描述】:

长话短说,我收到了这个查询(针对论坛世界进行了一些编辑)以使其正常工作,以便开始创建报告。 3 CASE 语句存在一些问题(尝试在代码中添加注释以更好地解释正在发生的事情)。所有数据都从同一个表/视图中提取。

我知道我需要创建一些嵌套的 SELECT 语句才能使其正常工作,但我很挣扎。我想要发生的是......

  1. CASE 2 仅在 CASE 1 不为 NULL 时运行,其中列将是 (amd_month + 1 个月) 的结果。格式为 YYYYMM

  2. CASE 3 仅在 CASE 2 不为 NULL 时运行,其中列将是 (ext_srg_start_date + 6 个月) 的结果。格式为 YYYYMM

    SELECT
    part,
    amd_month,
    amd   actual_demand,
    round(roll_12amd * 1.15) srg_lmt,
    round(roll_12amd * 1.5) ext_srg_lmt,
    -- CASE: 1 
    -- calculate level- COMPLETE
    CASE
    WHEN (amd > roll_12amd * 1.5) THEN 'Extreme Surge'
    WHEN (amd > roll_12amd * 1.15) THEN 'Surge'
    ELSE NULL
    END AS srg_nt,
    -- CASE: 2
    -- if amd_month = 12, (+1 year to) and (-11 from month) from ext_srg_start_date, 
    -- else +1 month to ext_srg_start_date - COMPLETE
    CASE
    WHEN substr(amd_month, 5, 2) IN (
        '12'
    ) THEN concat(TO_CHAR(substr(amd_month, 1, 4) + 1), lpad(TO_CHAR(substr(amd_month, 5, 2) - 11), 2, '0'))
    ELSE concat(substr(amd_month, 1, 4), lpad(TO_CHAR(substr(amd_month, 5, 2) + 1), 2, '0'))
    END AS ext_srg_start_date,
    ---- CASE: 3
    ---- +6 to ext_srg_start_date - IN PROGRESS
    CASE
    WHEN substr(amd_month, 5, 2) IN (
        '01',
        '02',
        '03',
        '04',
        '05',
        '06'
    ) THEN concat(substr(amd_month, 1, 4), lpad(TO_CHAR(substr(amd_month, 5, 2) + 6), 2, '0'))
    ELSE concat(TO_CHAR(substr(amd_month, 1, 4) + 1), lpad(TO_CHAR(substr(amd_month, 5, 2) - 6), 2, '0'))
    END AS ext_srg_carry_date
    FROM
    connect.table
    

任何帮助都会很棒。谢谢!

【问题讨论】:

  • 哪个数据库?
  • to_char?看起来是甲骨文。
  • 是的,它是甲骨文。对不起,我应该添加的。我相对确定有一个更简单的解决方案可以让日期字段按预期显示,但这并不是我目前的主要关注点。
  • AMD_Month 的数据类型是什么?日期(希望)还是 Varchar2?更好的是,您能否提供connect.table 的描述或至少是相关列和一些示例数据?
  • @Sentinel AMD_MONTH - VARCHAR2 (6 CHAR) .... PART - VARCHAR2 (25 CHAR) ... AMD - NUMBER

标签: sql oracle select subquery case


【解决方案1】:

如果 AMD_Month 是日期数据类型,您可以取消 case 语句 2 和 3,如果不是,您也可以取消它们,但需要额外的步骤:

如果 AMD_Month 是 Date 列,则 ext_srg_start_date 和 ext_srg_carry_date 可以定义为:

...
, AMD_Month + INTERVAL '1' MONTH ext_srg_start_date
, AMD_Month + INTERVAL '6' MONTH ext_srg_carry_date
...

如果 AMD_Month 是一个字符串,那么您首先需要将其转换为日期,我猜然后将结果转换回字符串:

...
, TO_CHAR( TO_DATE( AMD_Month, 'YYYYMM')
         + INTERVAL '1' MONTH, 'YYYYMM') ext_srg_start_date
, TO_CHAR( TO_DATE( AMD_Month, 'YYYYMM')
         + INTERVAL '6' MONTH, 'YYYYMM') ext_srg_carry_date
...

将日期数据类型存储为日期或时间戳比将它们存储为字符串时,日期算术的效果要好得多。

【讨论】:

  • 看起来我误读了您的规范的一部分,这部分表明ext_srg_carry_dateext_srg_start_date 加6 个月,比AMD_Month 加1 个月,所以不要使用INTERVAL '6' MONTH我应该把INTERVAL '7' MONTH
  • 效果很好。我知道有一种方法可以更轻松地做到这一点,我想我只是看着大局而感到困惑。不知道为什么他们将日期存储为 varchar2。非常感谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-11-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-03-12
  • 2016-12-10
  • 1970-01-01
相关资源
最近更新 更多