我想在一个单元格中显示几个单元格值。所以我使用这个查询:
select LISTAGG(fc.DESCRIPTION, ';'||chr(10))WITHIN GROUP (ORDER BY fc.SWITCH_NAME) AS DESCRIP from "ORS".SWITCH_OPERATIONS fc
group by fc.SWITCH_NAME
工作正常。但是当我将其与我的主(完整)查询合并时,我得到的错误为:错误代码1427,SQL状态21000:ORA-01427:单行子查询返回多行
这是我的完整查询:
SELECT
TRACK_EVENT.LOCATION,
TRACK_EVENT.ELEMENT_NAME,
(select COUNT(*) from ORS.TRACK_EVENT b where (b.ELEMENT_NAME = sw.SWITCH_NAME)AND (b.ELEMENT_TYPE = 'SWITCH')AND (b.EVENT_TYPE = 'I')AND (b.ELEMENT_STATE = 'NORMAL' OR b.ELEMENT_STATE = 'REVERSE'))as COUNTER,
(select COUNT(*) from ORS.SWITCH_OPERATIONS fc where TRACK_EVENT.ELEMENT_NAME = fc.SWITCH_NAME and fc.NO_CORRESPONDENCE = 1 )as FAIL_COUNT,
(select MAX(cw.COMMAND_TIME) from ORS.SWITCH_OPERATIONS cw where ((TRACK_EVENT.ELEMENT_NAME = cw.SWITCH_NAME) and (cw.NO_CORRESPONDENCE = 1)) group by cw.SWITCH_NAME ) as FAILURE_DATE,
(select LISTAGG(fc.DESCRIPTION, ';'||chr(10))WITHIN GROUP (ORDER BY fc.SWITCH_NAME) AS DESCRIP from "ORS".SWITCH_OPERATIONS fc
group by fc.SWITCH_NAME)
FROM
ORS.SWITCH_OPERATIONS sw,
ORS.TRACK_EVENT TRACK_EVENT
WHERE
sw.SEQUENCE_ID = TRACK_EVENT.SEQUENCE_ID
答案 0 :(得分:3)
SELECT
列表中的子查询不仅需要返回一行(或者它们用于单一比较的任何时间,例如<
,=
等),但是它们在该上下文中的使用倾向于使数据库执行它们RBAR
- 逐行 - 痛苦行。也就是说,它们比它们应该更慢并消耗更多的资源。
通常,除非子查询外部的结果集只包含几行,否则您希望将子查询构造为表引用的一部分。即,像:
SELECT m.n, m.z, aliasForSomeTable.a, aliasForSomeTabe.bSum
FROM mainTable m
JOIN (SELECT a, SUM(b) AS bSum
FROM someTable
GROUP BY a) aliasForSomeTable
ON aliasForSomeTable.a = m.a
这可以通过其他方式使您受益 - 例如,从同一个表引用中获取多个列更容易。
假设LISTAGG(...)
可以包含在其他聚合函数中,您可以将查询更改为:
SELECT Track_Event.location, Track_Event.element_name,
Counted_Events.counter,
Failure.fail_count, Failure.failure_date, Failure.descrip
FROM ORS.Track_Event
JOIN ORS.Switch_Operations
ON Switch_Operations.sequence_id = Track_Event.sequence_id
LEFT JOIN (SELECT element_name, COUNT(*) AS counter
FROM ORS.Track_Event
WHERE element_type = 'SWITCH'
AND event_type = 'I'
AND element_state IN ('NORMAL', 'REVERSE')
GROUP BY element_name) Counted_Events
ON Counted_Events.element_name = Switch_Operations.swicth_name
LEFT JOIN (SELECT switch_name,
COUNT(CASE WHEN no_correspondence = 1 THEN '1' END) AS fail_count,
MAX(CASE WHEN no_correspondence = 1 THEN command_time END) AS failure_date,
LISTAGG(description, ';' || CHAR(10)) WITHIN GROUP (ORDER BY command_time) AS descrip
FROM ORS.Switch_Operations
GROUP BY switch_name) Failure
ON Failure.switch_name = Track_Event.element_name
此查询被写入(尝试)保留原始查询的语义。我不完全确定你实际需要,但没有样本开始数据和期望的结果,我无法告诉你如何改进它。例如,我有点怀疑外部查询中Switch_Operations
的需要,以及LISTAGG(...)
在no_correspondence <> 1
的行上运行的事实。我确实更改了LISTAGG(...)
的顺序,因为原始列不会做任何事情(因为订单方式与分组相同),所以不会是稳定的排序。
答案 1 :(得分:1)
单行子查询返回多行。
此错误消息是自描述的
返回的字段不能有多个值,子查询返回多行
在完整查询中,指定要返回的字段。最后一个字段需要来自子查询的单个值,而是获得多个行。
我对你正在使用的数据一无所知,但要么你必须确保子查询只返回一行,要么你必须重新设计包装查询(可能在适当的时候使用连接)。