我需要使用order by和rownum构建一个查询,但不使用sublect。 需要获取有序查询的第一行。
换句话说,我想要
的结果select * from (
SELECT CAMP1,ORDERCAMP
FROM TABLENAME
ORDER BY ORDERCAMP) where rownum=1;
但不使用子选择。有可能吗?
我有一个Oracle 11.你可以说这是我的整个查询:
SELECT T1.CAMP_ID,
T2.CAMP
(SELECT OT.CAMP
FROM OTHERTABLE OT
WHERE OT.FK_TO_TABLE1=T1.CAMP_ID
ORDER BY OT.ORDERCAMP
)
FROM TABLE1 T1,
TABLE2 T2
WHERE T1.FK_TO_T2=T2.PK;
子查询返回多行,我不能使用另一个子查询,如
SELECT T1.CAMP_ID,
T2.CAMP
(SELECT *
FROM
(SELECT OT.CAMP
FROM OTHERTABLE OT
WHERE OT.FK_TO_TABLE1=T1.CAMP_ID
ORDER BY OT.ORDERCAMP
)
WHERE ROWNUM=1
)
FROM TABLE1 T1,
TABLE2 T2
WHERE T1.FK_TO_T2=T2.PK;
SELECT CAMP1,ORDERCAMP FROM TABLE2 ORDER BY ORDERCAMP
因为T1.CAMP_ID
是第三级子查询中的无效标识符。
我希望我已经足够解释了自己。
答案 0 :(得分:3)
您当前的查询(没有无效的ORDER BY
)获得ORA-01427: single-row subquery returns more than one row
。您可以嵌套子查询,但加入时只能返回一个级别;所以如果你这样做了:
SELECT T1.CAMP_ID, T2.CAMP,
(SELECT CAMP FROM
FROM
(SELECT OT.CAMP
FROM OTHERTABLE OT
WHERE OT.FK_TO_TABLE1=T1.CAMP_ID
ORDER BY OT.ORDERCAMP
)
WHERE ROWNUM = 1)
FROM TABLE1 T1, TABLE2 T2 WHERE T1.FK_TO_T2=T2.PK;
...然后你会得到ORA-00904: "T1"."CAMP_ID": invalid identifier
。因此,大概是你的问题。
你可以做的是加入到第三个表,并使用分析ROW_NUMBER()
函数来分配行号,然后使用围绕整个事物的外部选择来仅查找具有最低值的记录ORDERCAMP
:
SELECT CAMP_ID, CAMP, OT_CAMP
FROM (
SELECT T1.CAMP_ID, T2.CAMP, OT.CAMP AS OT_CAMP,
ROW_NUMBER() OVER (PARTITION BY T1.CAMP_ID ORDER BY OT.ORDERCAMP) AS RN
FROM TABLE2 T2
JOIN TABLE1 T1 ON T1.FK_TO_T2=T2.PK
JOIN OTHERTABLE OT ON OT.FK_TO_TABLE1=T1.CAMP_ID
)
WHERE RN = 1;
ROW_NUMBER()
可以对T1.CAMP_ID
主键值或其他任何唯一值进行分区。
SQL Fiddle demo,包括内部查询自行运行,以便您可以看到在应用外部过滤器之前分配的RN
个数字。
另一种方法是使用汇总KEEP DENSE_RANK FIRST
function
SELECT T1.CAMP_ID, T2.CAMP,
MAX(OT.CAMP) KEEP (DENSE_RANK FIRST ORDER BY OT.ORDERCAMP) AS OT_CAMP
FROM TABLE2 T2
JOIN TABLE1 T1 ON T1.FK_TO_T2=T2.PK
JOIN OTHERTABLE OT ON OT.FK_TO_TABLE1=T1.CAMP_ID
GROUP BY T1.CAMP_ID, T2.CAMP;
哪个更短,不需要内部查询。我不确定一个人是否有任何真正的优势。
答案 1 :(得分:1)
在最新版本的Oracle中,您可以执行以下操作:
SELECT CAMP1, ORDERCAMP
FROM TABLENAME
ORDER BY ORDERCAMP
FETCH FIRST 1 ROWS ONLY;
否则,我认为你需要某种子查询。
答案 2 :(得分:-2)
您可以使用LIMIT或SELECT TOP 1
SELECT CAMP1, ORDERCAMP FROM TABLENAME ORDER BY ORDERCAMP LIMIT 1