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;