Oracle SELECT TOP 10logging
我在Oracle中有一个SQL语句的大问题。 我想selectSTORAGE_DBsorting的TOP 10logging,这些logging不在其他select语句的列表中。
这一个工作正常的所有logging:
SELECT DISTINCT APP_ID, NAME, STORAGE_GB, HISTORY_CREATED, TO_CHAR(HISTORY_DATE, 'DD.MM.YYYY') AS HISTORY_DATE FROM HISTORY WHERE STORAGE_GB IS NOT NULL AND APP_ID NOT IN (SELECT APP_ID FROM HISTORY WHERE TO_CHAR(HISTORY_DATE, 'DD.MM.YYYY') = '06.02.2009')
但是,当我join
AND ROWNUM <= 10 ORDER BY STORAGE_GB DESC
我正在得到某种“随机”logging。 我觉得因为限制在订单之前。
有人有一个好的解决scheme? 另一个问题:这个查询是真的很慢(10K +logging)
你需要把你当前的查询放在子查询中,如下所示:
SELECT * FROM ( SELECT DISTINCT APP_ID, NAME, STORAGE_GB, HISTORY_CREATED, TO_CHAR(HISTORY_DATE, 'DD.MM.YYYY') AS HISTORY_DATE FROM HISTORY WHERE STORAGE_GB IS NOT NULL AND APP_ID NOT IN (SELECT APP_ID FROM HISTORY WHERE TO_CHAR(HISTORY_DATE, 'DD.MM.YYYY') ='06.02.2009') ORDER BY STORAGE_GB DESC ) WHERE ROWNUM <= 10
Oracle在返回后将rownum应用于结果。
您需要在返回后过滤结果,因此需要子查询。 您也可以使用RANK()函数来获取Top-N结果。
对于性能尝试使用NOT EXISTS
代替NOT IN
。 看到这更多。
对于糟糕的performance,可能会有很多事情,而且这应该是一个单独的问题。 但是,有一个明显的问题可能是一个问题:
WHERE TO_CHAR(HISTORY_DATE, 'DD.MM.YYYY') = '06.02.2009')
如果HISTORY_DATE确实是一个date列,并且它有一个索引,那么这个重写将会更好:
WHERE HISTORY_DATE = TO_DATE ('06.02.2009', 'DD.MM.YYYY')
这是因为数据types转换禁止使用B树索引。
你会得到一个明显的随机集合,因为ROWNUM在ORDER BY之前被应用。 因此,您的查询需要前10行并对其进行sorting.0要select前十名工资,您应该在子查询中使用分析函数,然后过滤:
select * from (select empno, ename, sal, row_number() over(order by sal desc nulls last) rnm from emp) where rnm<=10
如果您使用的是Oracle 12c,则可以使用:
只取下N行
SELECT DISTINCT APP_ID, NAME, STORAGE_GB, HISTORY_CREATED, TO_CHAR(HISTORY_DATE, 'DD.MM.YYYY') AS HISTORY_DATE FROM HISTORY WHERE STORAGE_GB IS NOT NULL AND APP_ID NOT IN (SELECT APP_ID FROM HISTORY WHERE TO_CHAR(HISTORY_DATE, 'DD.MM.YYYY') ='06.02.2009') ORDER BY STORAGE_GB DESC FETCH NEXT 10 ROWS ONLY
更多信息: http : //docs.oracle.com/javadb/10.5.3.0/ref/rrefsqljoffsetfetch.html
尝试SELECT * FROM用户FETCH NEXT 10 ROWS ONLY;
你可以简单地使用TOP子句
selectTOP 10 *从表;
要么
SELECT column_name(s)FROM table_name WHERE ROWNUM <= number;