尝试选择表行,然后使用子查询生成单行列表(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)
问题似乎是表'管理员'中的主要查询字段'代码'在列表生成查询中不起作用
答案 0 :(得分:2)
我可以用一个简单的例子重现你的发现。考虑:
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_connect_by_path
或
*编写一个将代码作为参数的函数,并输出您选择的结果。
如果您想要一个示例,请向我们提供CREATE TABLE和示例数据。
答案 1 :(得分:0)
我猜“管理员”表格中没有列“代码”...这只是一个小错误。如果有,你不想加入管理员的房间代码,而是像“admincode = admins.code”。
答案 2 :(得分:0)
根据您的数据库图表,最好的方法是使用自定义string aggregation功能,然后执行分组。这类似于mysql group_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
答案 3 :(得分:0)
尝试重写子查询
(
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()