【问题标题】:How to filter with short names in where clause如何在 where 子句中使用短名称进行过滤
【发布时间】:2018-06-04 15:41:46
【问题描述】:

我有一个问题,我们如何在 case 语句 OTHER 下的 where 子句中过滤一个值,然后过滤 DB 端的实际值。

例如

WHERE
'&mwb_header.transport_mode' --want to create a parameter
(CASE WHEN (mwb_header.transport_mode='O')   THEN 'OCEAN' 
       WHEN (mwb_header.transport_mode='A')     THEN 'AIR' 
    WHEN (mwb_header.transport_mode='R')     THEN 'RAIL' 
    WHEN (mwb_header.transport_mode='T')     THEN 'TRUCK' 
  ELSE 'OTHERS' END) ;

数据库端此列的实际值为“O”、“A”、“R”、“T”和“OTH”,但我只想将任何值用于过滤器,如“O”或'OCEAN' 过滤正确的结果。

【问题讨论】:

    标签: oracle parameters case where


    【解决方案1】:

    您的代码看起来不错,似乎可以工作:

    CREATE TABLE mwb_header (i NUMBER, transport_mode VARCHAR2(3));
    INSERT INTO mwb_header VALUES (1, 'O');
    INSERT INTO mwb_header VALUES (2, 'A');
    INSERT INTO mwb_header VALUES (3, 'R');
    INSERT INTO mwb_header VALUES (4, 'T');
    INSERT INTO mwb_header VALUES (5, 'OTH');
    
    SELECT *
      FROM mwb_header
     WHERE 'OCEAN' = (CASE WHEN (mwb_header.transport_mode='O') THEN 'OCEAN' 
                           WHEN (mwb_header.transport_mode='A') THEN 'AIR' 
                           WHEN (mwb_header.transport_mode='R') THEN 'RAIL' 
                           WHEN (mwb_header.transport_mode='T') THEN 'TRUCK' 
                                                                ELSE 'OTHERS' 
                       END) ;
    

    返回

    id  transport_mode
    1   O
    

    我个人更喜欢较短的语法

    SELECT *
      FROM mwb_header
     WHERE 'OCEAN' = (CASE mwb_header.transport_mode
                           WHEN 'O' THEN 'OCEAN'
                           WHEN 'A' THEN 'AIR'
                           WHEN 'R' THEN 'RAIL'
                           WHEN 'T' THEN 'TRUCK'
                                    ELSE 'OTHERS'
                       END);
    

    【讨论】:

    • 感谢您的回复。很抱歉,我没有正确理解您的观点,我有疑问; mwb_header.transport_mode 是DB端提供的一列。我想将其作为参数,以便用户可以在运行时输入它的值。我们如何为提供的 case 语句传递值(O 或 OCEAN 等)
    【解决方案2】:

    如果您可以更改表结构,我建议将“虚拟列”添加到具有较长名称(如 OCEAN)的表中。

    数据是从真实列transport_mode 计算(或生成)的。它看起来像一个普通列,但没有任何内容存储在数据库中,而是在需要时计算。

    换句话说,我们将您从 WHERE 子句中从“O”转换为“OCEAN”的代码移到表定义中,以便所有人都可以使用它。

    ALTER TABLE mwb_header ADD (long_transport GENERATED ALWAYS AS (
      CASE transport_mode
           WHEN 'O' THEN 'OCEAN'
           WHEN 'A' THEN 'AIR'
           WHEN 'R' THEN 'RAIL'
           WHEN 'T' THEN 'TRUCK'
                    ELSE 'OTHERS'
       END));
    

    现在您(和所有其他查询)可以使用长名称:

    SELECT * from mwb_header WHERE long_transport='OCEAN';
    

    和短名一模一样:

    SELECT * from mwb_header WHERE transport_mode='O';
    

    结果将完全相同。

    更好的是,如果表有很多行,你甚至可以在计算列上放置一个索引来加快速度:

    CREATE INDEX mwb_short_transport_idx ON mwb_header(long_transport);
    

    【讨论】:

    • 非常感谢您的帮助!!
    猜你喜欢
    • 2013-09-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-18
    相关资源
    最近更新 更多