具有多个子查询的oracle查询

具有多个子查询的oracle查询,oracle,Oracle,尝试选择表行,然后使用子查询生成单行列表item1、item2、item3 无论如何,sql: select username, concat(firstname || ' ', lastname) as name, email, phone, ( select ltrim(sys_connect_by_path(res, ', '), ', ') from ( select count(*) over() as cnt,

尝试选择表行,然后使用子查询生成单行列表item1、item2、item3

无论如何,sql:

select 
  username,
  concat(firstname || ' ', lastname) as name,
  email,
  phone,
  (
  select 
    ltrim(sys_connect_by_path(res, ', '), ', ')
  from (
    select 
      count(*) over() as cnt, 
      row_number() over(order by ofield) as rnum, 
      (select name from rooms where code=roomcode) as res 
    from adminrooms
    where roomcode=admins.code) /*admins.code - come from main query but it gives error: invalid identifier*/
  where cnt=rnum start with rnum=1 connect by prior rnum=(rnum-1)
  ) as groups
from admins
where frozen=0 and (type <> 'root' or type is null)

问题似乎是表“admins”中的主查询字段“code”在列表生成查询中不起作用

我猜admins表中没有列代码。。。这只是一个小错误。如果有,您就不想加入adminrooms的roomcode,而是像admincode=admins.code这样的东西。

我可以用一个简单的例子重现您的发现。考虑:

SQL> SELECT (SELECT d1.dummy FROM dual d2) d2
  2    FROM dual D1;

D2
--
X
这是因为子查询d2可以看到主查询d1的行,但是如果我们添加一个级别,我会得到与您相同的错误:

SQL> SELECT (SELECT NULL FROM (SELECT d1.dummy FROM dual d3))
  2  FROM dual D1;

SELECT (SELECT NULL FROM (SELECT d1.dummy FROM dual d3))
FROM dual D1                     ~

ORA-00904: "D1"."DUMMY": invalid identifier
在这里,子查询D3看不到D1中的行的值

您必须修改您的查询: *将admin与adminrooms连接,然后使用sys\u connect\u by\u路径或 *编写一个函数,将代码作为参数,并输出选择的结果


如果您需要示例,请向我们提供创建表和示例数据。

根据您的db图,最好的方法是使用自定义函数,然后只执行分组操作。这类似于mysql组_concat

如果使用上述链接生成名为string_agg的函数,则可以在代码中按如下方式使用该函数:

select a.username, string_agg(c.name) from admins a, adminrooms b, groups c
where a.code=b.admincode
and b.groupcode=c.code
group by a.username
下面是string_agg函数创建脚本。只需将其作为脚本运行,您就可以从上面显示的链接获得上述函数:

CREATE OR REPLACE TYPE t_string_agg AS OBJECT
(
  g_string  VARCHAR2(32767),

  STATIC FUNCTION ODCIAggregateInitialize(sctx  IN OUT  t_string_agg)
    RETURN NUMBER,

  MEMBER FUNCTION ODCIAggregateIterate(self   IN OUT  t_string_agg,
                                       value  IN      VARCHAR2 )
     RETURN NUMBER,

  MEMBER FUNCTION ODCIAggregateTerminate(self         IN   t_string_agg,
                                         returnValue  OUT  VARCHAR2,
                                         flags        IN   NUMBER)
    RETURN NUMBER,

  MEMBER FUNCTION ODCIAggregateMerge(self  IN OUT  t_string_agg,
                                     ctx2  IN      t_string_agg)
    RETURN NUMBER
);
/
SHOW ERRORS


CREATE OR REPLACE TYPE BODY t_string_agg IS
  STATIC FUNCTION ODCIAggregateInitialize(sctx  IN OUT  t_string_agg)
    RETURN NUMBER IS
  BEGIN
    sctx := t_string_agg(NULL);
    RETURN ODCIConst.Success;
  END;

  MEMBER FUNCTION ODCIAggregateIterate(self   IN OUT  t_string_agg,
                                       value  IN      VARCHAR2 )
    RETURN NUMBER IS
  BEGIN
    SELF.g_string := self.g_string || ',' || value;
    RETURN ODCIConst.Success;
  END;

  MEMBER FUNCTION ODCIAggregateTerminate(self         IN   t_string_agg,
                                         returnValue  OUT  VARCHAR2,
                                         flags        IN   NUMBER)
    RETURN NUMBER IS
  BEGIN
    returnValue := RTRIM(LTRIM(SELF.g_string, ','), ',');
    RETURN ODCIConst.Success;
  END;

  MEMBER FUNCTION ODCIAggregateMerge(self  IN OUT  t_string_agg,
                                     ctx2  IN      t_string_agg)
    RETURN NUMBER IS
  BEGIN
    SELF.g_string := SELF.g_string || ',' || ctx2.g_string;
    RETURN ODCIConst.Success;
  END;
END;
/
SHOW ERRORS


CREATE OR REPLACE FUNCTION string_agg (p_input VARCHAR2)
RETURN VARCHAR2
PARALLEL_ENABLE AGGREGATE USING t_string_agg;
/
SHOW ERRORS

尝试重写子查询

   (
    select 
      count(*) over() as cnt, 
      row_number() over(order by ofield) as rnum, 
      (select name from rooms where code=roomcode) as res 
    from adminrooms
    where roomcode=admins.code)
如主查询中的表所示

 ... from admins, 
       (
        select 
          roomcode,
          count(*) over() as cnt, 
          row_number() over(order by ofield) as rnum, 
          (select name from rooms where code=roomcode) as res 
        from adminrooms) t
 where t.roomcode = admins.code...

使用wmsys.WM_CONCAT而不是sys_connect_by_path检查表并验证列,idd是一个输入错误,但现在:where admincode=admins.code给出了admins.code:无效标识符两个查询单独工作,但不能一起工作:您需要提供源表和数据的更多细节以及预期结果看起来像。我还将详细介绍Oracle版本。更高版本实现了一个PIVOT子句来将行转换为列。它可以正常工作,但是我要使用它的db没有函数等的权限,所以唯一的选项是表连接:注意wmsys.wm_concat是一个未记录的函数。在生产环境中使用它之前,您需要三思而后行。