36

有没有办法让子查询在 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 解决所有这些问题。您根本不需要这样的子查询(甚至一列也不需要)。但他们在那里。那么我可以以这种方式使用它们还是根本不可能?

4

7 回答 7

23

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

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
于 2012-09-18T08:08:43.450 回答
23

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

恐怕您不能从单个标量子查询返回多个列,不。

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

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

于 2012-09-18T09:26:06.030 回答
8

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

  1. 您可以使用串联来一次获取多个列

    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 对象

    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
    
于 2012-09-18T10:15:08.690 回答
3

你不能像这样使用 JOIN 吗?

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

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

于 2012-09-18T08:10:24.590 回答
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 ....
于 2014-05-19T10:56:20.480 回答
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

如果没有从b到从a到马赫行的行,则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
于 2017-06-20T12:11:53.683 回答
1

查看此网站: 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);    
于 2017-06-20T12:01:33.613 回答