是否可以从子查询中获取多个值?

时间:2012-09-18 08:05:37

标签: sql oracle

有没有办法让子查询在oracle db中返回多个列? (我知道这个特定的sql会导致错误,但它总结了我想要的东西)

select
    a.x,
    ( select b.y, b.z from b where b.v = a.v),
from a

我想要一个这样的结果:

a.x | b.y | b.z
---------------
1   | 2   | 3

我知道通过连接可以解决这个问题,但这不是我要求的。

我的问题很简单,如果有任何方法,从子查询中获取两个或更多值?也许使用双重解决方法?那么没有实际的连接,但每行都有一个新的子查询?

编辑:这是一个主要问题。你知道,你可以使用join解决所有这些问题。您根本不需要这样的子查询(甚至不需要一列)。但他们在那里。那么我可以这样使用它们还是根本不可能?

7 个答案:

答案 0 :(得分:18)

这是不正确的,但你可以试试这个:

select
    a.x,
    ( select b.y from b where b.v = a.v) as by,
    ( select b.z from b where b.v = a.v) as bz
from a

您也可以在联接中使用子查询

 select
        a.x,
        b.y,
        b.z
    from a
    left join (select y,z from b where ... ) b on b.v = a.v

   select
        a.x,
        b.y,
        b.z
    from a
    left join b on b.v = a.v

答案 1 :(得分:16)

Select子句中的子查询(在您的情况下)也称为标量子查询,这意味着它是表达式的一种形式。这意味着它只能返回一个值。

我担心你不能从单个标量子查询返回多个列,没有。

以下是有关Oracle标量子查询的更多信息:

http://docs.oracle.com/cd/B19306_01/server.102/b14200/expressions010.htm#i1033549

答案 2 :(得分:7)

以下两种方法可以在标量子查询(或内联子查询)中获取多个列,并仅查询查询表一次。这有点令人费解,但在某些特殊情况下可能非常有效。

  1. 您可以使用连接来获取several columns at once

    SELECT x, 
           regexp_substr(yz, '[^^]+', 1, 1) y,
           regexp_substr(yz, '[^^]+', 1, 2) z
      FROM (SELECT a.x,
                   (SELECT b.y || '^' || b.z yz
                      FROM b
                     WHERE b.v = a.v)
                      yz
              FROM a)
    

    您需要确保列表中没有列包含分隔符。

  2. 您也可以使用SQL objects

    CREATE OR REPLACE TYPE b_obj AS OBJECT (y number, z number);
    
    SELECT x, 
           v.yz.y y,
           v.yz.z z
      FROM (SELECT a.x,
                   (SELECT b_obj(y, z) yz
                      FROM b
                     WHERE b.v = a.v)
                      yz
              FROM a) v
    

答案 3 :(得分:3)

你不能像这样使用JOIN吗?

SELECT
a.x , b.y, b.z 
FROM a 
LEFT OUTER JOIN b ON b.v = a.v

(我不知道Oracle语法。所以我编写了SQL语法)

答案 4 :(得分:2)

在Oracle查询中

select a.x
            ,(select b.y || ',' || b.z
                from   b
                where  b.v = a.v
                and    rownum = 1) as multple_columns
from   a

可以转换为:

select a.x, b1.y, b1.z
from   a, b b1
where  b1.rowid = (
       select b.rowid
       from   b
       where  b.v = a.v
       and    rownum = 1
)

当我们想要防止表A的重复时很有用。 同样,我们可以增加表的数量:

.... where (b1.rowid,c1.rowid) = (select b.rowid,c.rowid ....

答案 5 :(得分:2)

您可以使用cross apply

select
    a.x,
    bb.y,
    bb.z
from
    a
    cross apply
    (   select b.y, b.z
        from b
        where b.v = a.v
    ) bb

如果 a 中没有来自 a 的行到mach行,则cross apply将不会返回行。如果您需要这样的行,请使用outer apply

如果您只需要为 a 中的每一行找到一个特定行,请尝试:

    cross apply
    (   select top 1 b.y, b.z
        from b
        where b.v = a.v
        order by b.order
    ) bb

答案 6 :(得分:0)

查看此网页: http://www.w3resource.com/sql/subqueries/multiplee-row-column-subqueries.php

使用示例

select ord_num, agent_code, ord_date, ord_amount  
from orders  
where(agent_code, ord_amount) IN  
(SELECT agent_code, MIN(ord_amount)  
FROM orders   
GROUP BY agent_code);    
相关问题