【问题标题】:Merge few queries "SELECT INTO.." into one将几个查询“SELECT INTO..”合并为一个
【发布时间】:2019-11-24 19:54:53
【问题描述】:

我有如下选择列表:

  SELECT id
  INTO   val_abc
  FROM   table_x
  WHERE  symbol = 'abc';

  SELECT id
  INTO   val_xyz
  FROM   table_x
  WHERE  symbol = 'xyz';

  SELECT id...

是否有可能将 SAME TABLE(!) 中的几个 SELECTS 合并为一个?

【问题讨论】:

  • 由于每个选择检索不同的行,这将是不可能的(如果是,这也不会使代码更具可读性)

标签: sql oracle merge


【解决方案1】:

是的,您可以像这里一样组合这些查询:

select max(case symbol when 'abc' then id end),
       max(case symbol when 'def' then id end),
       max(case symbol when 'xyz' then id end)
  into val_abc, val_def, val_xyz
  from table_x
  where symbol in ('abc', 'def', 'xyz');

甚至使用数据透视(Oracle 11 或更高版本):

select v1, v2, v3
  into val_abc, val_def, val_xyz
  from (select id, symbol from table_x)
  pivot (max(id) for symbol in ('abc' v1, 'def' v2, 'xyz' v3));

dbfiddle demo

注意:如果您的查询遇到多个匹配行,则应用程序会在没有值时抛出错误too many rowsno data found。我的解决方案使用聚合,因此不会出现错误 - 如果没有找到,它需要最大值或 null。 table_x 是否每个符号只有一个匹配的 id 无关紧要,但请注意这一点。

【讨论】:

    【解决方案2】:

    是的,有几种方法,例如

    select id
    from tablex
    where symbol in ('abc', 'xyz')
    

    select id 
    from tablex
    where symbol = 'abc'
       or symbol = 'xyz'
    

    select id 
    from tablex
    where symbol = 'abc'
    union all
    select id
    from tablex
    where symbol = 'xyz'
    

    【讨论】:

    • aww... 对不起,我忘了添加子句 INTO。可以再看一遍吗?
    • 显然,如果val_abc 是一个标量变量(例如,声明为val_abc number;),那将不起作用,因为您不能将许多行放入这样的变量。您可以在循环中执行此操作,或将行数限制为恰好一个(通过应用where rownum = 1),但我想这不是您想要的。或者,您可以声明一个自定义类型变量(一个集合)并使用bulk collect。可能还有其他选择,但是 - 请解释您要解决的问题,因为我们的建议取决于它。
    【解决方案3】:

    如果你真的想表达,你可以使用joins 来表达:

    SELECT abc.id, xyz.id
    INTO val_abc, val_xyz
    FROM table_x abc JOIN
         table_x xyz
         ON abc.symbol = 'abc' AND
            xyz.symbol = 'xyz';
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多