Rownum语句返回与没有它时不同的行。

14 浏览
0 Comments

Rownum语句返回与没有它时不同的行。

我有一个选择语句,返回拥有最少员工人数的CLERKS的部门编号,但由于数据库中的数据,它返回了两个部门。当我添加rownum=1时,它给我返回了一个完全不同的部门编号,该部门拥有最多的CLERKS,我不知道为什么会这样。希望能得到帮助。

select deptno from emp where job='CLERK' group by deptno 
having count(job)=(select min(count(job)) from emp where job='CLERK'group by deptno);

我尝试在主选择语句和子选择语句中使用rownum,但结果相同...我甚至使用了order by,但结果仍然相同。

select deptno from emp where rownum=1 and job='CLERK' group by deptno 
having count(job)=(select min(count(job)) from emp where job='CLERK'group by deptno) order by deptno;

以下是带有rownum和order by的相同语句。

0
0 Comments

问题的原因是where子句在order by之前应用。解决方法是先排序,然后再应用rownum

在Oracle数据库中,rownum语句返回的行与没有使用rownum的语句返回的行不同。这是一个Oracle特有的问题。而在MS SQL Server中,TOP关键字和MySQL中的LIMIT关键字都是在order by子句之后应用的。

在Oracle数据库12c(12.1)中,有一种新的特性可以选择从第k行到第k+m行:offset k rows fetch next m rows only。我建议使用这个特性来替代上面的解决方法。

如果存在两个或多个部门具有相同的部门号,那怎么办呢?不用担心,有一种变体可以返回所有并列的行:

select deptno from emp 
 where job='CLERK' 
 group by deptno 
having count(job)=(select min(count(job)) from emp where job='CLERK'group by deptno) 
order by deptno
fetch next 1 rows with ties

以上是解决问题的原因和方法。

0
0 Comments

在Oracle 12c中,引入了新的Top-N行限制功能。这个功能可以很方便地获取指定数量的行。

例如,我们可以使用以下语句获取工资最高的前5个员工的工号和工资:

SELECT empno, sal
FROM emp
ORDER BY sal DESC
FETCH FIRST 5 ROWS ONLY;

运行以上代码,我们可以得到以下结果:

EMPNO        SAL
---------- ----------
  7839       5000
  7788       3000
  7902       3000
  7566       2975
  7698       2850

这个新的功能非常实用,可以简化我们的查询语句。

然而,有些用户在使用这个功能时遇到了一个问题。他们发现,当他们在查询中使用了ROWNUM语句时,得到的结果和不使用ROWNUM语句时不一样。

具体来说,用户发现当他们在查询中使用了ROWNUM语句时,得到的结果中缺少了一些行。

例如,以下是一个使用ROWNUM语句的示例:

SELECT empno, sal, ROWNUM
FROM emp
WHERE ROWNUM <= 5
ORDER BY sal DESC;

运行以上代码,我们得到以下结果:

EMPNO        SAL    ROWNUM
---------- ---------- ----------
  7839       5000          1
  7902       3000          2
  7788       3000          3
  7566       2975          4
  7698       2850          5

可以看到,结果中缺少了一行,即工资最高的员工的信息。

这个问题的原因是ROWNUM是在查询结果返回后才进行计算的。所以,在使用ROWNUM语句时,ORDER BY子句会先进行排序,然后再计算ROWNUM。

为了解决这个问题,我们可以使用子查询来实现类似的功能。具体来说,我们可以先对结果进行排序,然后再使用ROWNUM语句。

以下是一个使用子查询的示例:

SELECT empno, sal, ROWNUM
FROM (
  SELECT empno, sal
  FROM emp
  ORDER BY sal DESC
)
WHERE ROWNUM <= 5;

运行以上代码,我们得到以下结果:

EMPNO        SAL    ROWNUM
---------- ---------- ----------
  7839       5000          1
  7788       3000          2
  7902       3000          3
  7566       2975          4
  7698       2850          5

可以看到,使用子查询后,我们得到了正确的结果,工资最高的员工的信息也包含在内。

通过使用子查询,我们可以解决ROWNUM语句返回不正确结果的问题。这样,我们就可以在Oracle 12c中充分利用新的Top-N行限制功能,简化我们的查询语句。

0