【问题标题】:Combine CASE and IN结合 CASE 和 IN
【发布时间】:2020-10-19 21:49:44
【问题描述】:

我正在处理分层数据,其中计划 (PGM) 和公立学校 (PUB) 属于学区 (DIS)。我需要查看一个 District 的所有子记录,因此我尝试使用 where 子句,其中我说子记录的类别应该是 'DIS'、'PUB' 或 'PGM'。

但是,我在此处尝试使用的代码不起作用 - 一旦我在第一个 WHEN 子句中列出多个值,我就会收到 ORA-00907:缺少右括号错误消息。

我怎样才能重写它,以便它允许我选择与多个可能值之一匹配的记录?

WHERE o.cat IN
    CASE (SELECT CAT from ads_organizations where org_id = :CUR_ORGID)
        WHEN 'DIS' THEN ('DIS', 'PUB', 'PGM')
        WHEN 'PUB' THEN ('PUB')
        WHEN 'PRI' THEN ('PRI')
    END

【问题讨论】:

    标签: sql oracle subquery case where-clause


    【解决方案1】:

    使用布尔逻辑。不需要case 表达式:

    FROM . . . CROSS JOIN
         (SELECT CAT from ads_organizations where org_id = :CUR_ORGID) ao
    WHERE (ao.cat = 'DIS' AND o.cat IN ('DIS', 'PUB', 'PGM')) OR
          (ao.cat = 'PUB' AND o.cat = 'PUB') OR
          (ao.cat = 'PRI' AND o.cat = 'PRI')
    

    这又可以简化为:

    WHERE (ao.cat = o.cat) OR
          (ao.cat = 'DIS' AND o.cat IN ('PUB', 'PGM')
    

    但是,这取决于cats 可以采用的所有值

    【讨论】:

      【解决方案2】:

      我会推荐布尔逻辑而不是case 表达式;它为条件提供了更大的灵活性。此外,您可以使用 exists 将逻辑移动到子查询本身。

      您的伪代码的相当直接的翻译是:

      where exists (
          select 1 
          from ads_organizations ao
          where 
              ao.org_id = :CUR_ORGID
              and (
                  (ao.cat in ('PUB', 'PRI') and ao.cat = o.cat)
                  or (ao.cat = 'DIS' and o.cat in ('DIS', 'PUB', 'PGM'))
              )
      )
      

      可能,这也可以表述为:

      where exists (
          select 1 
          from ads_organizations ao
          where 
              ao.org_id = :CUR_ORGID
              and (
                  ao.cat = o.cat
                  or (ao.cat = 'DIS' and o.cat in ('PUB', 'PGM'))
              )
      )
      

      【讨论】:

        猜你喜欢
        • 2013-10-03
        • 2022-01-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多