first / last vs min / max。 ORACLE。 SQL

时间:2013-07-04 18:44:19

标签: sql oracle

以下是查询和查询结果:

SELECT empno,
       deptno,
       sal,
       MIN(sal) KEEP (DENSE_RANK FIRST ORDER BY sal) OVER (PARTITION BY deptno) "Lowest",
       MAX(sal) KEEP (DENSE_RANK LAST ORDER BY sal) OVER (PARTITION BY deptno) "Highest"
FROM   emp
ORDER BY deptno, sal;

     EMPNO     DEPTNO        SAL     Lowest    Highest
---------- ---------- ---------- ---------- ----------
      7934         10       1300       1300       5000
      7782         10       2450       1300       5000
      7839         10       5000       1300       5000
      7369         20        800        800       3000
      7876         20       1100        800       3000
      7566         20       2975        800       3000
      7788         20       3000        800       3000
      7902         20       3000        800       3000
      7900         30        950        950       2850
      7654         30       1250        950       2850
      7521         30       1250        950       2850
      7844         30       1500        950       2850
      7499         30       1600        950       2850
      7698         30       2850        950       2850

SQL>

是否会返回相同的结果没有 KEEP语句?为什么不呢?

P.S。我自己会检查它,但是没有在当前机器上访问数据库。

2 个答案:

答案 0 :(得分:3)

根据你的标签,我假设你在Oracle:

  • Example with the KEEP statement.

    EMPNO | DEPTNO  | SAL   | LOWEST | HIGHEST
    7934  | 10      | 1300  | 1300   | 5000
    7782  | 10      | 2450  | 1300   | 5000
    7839  | 10      | 5000  | 1300   | 5000
    7369  | 20      |  800  |  800   | 3000
    7876  | 20      | 1100  |  800   | 3000
    7566  | 20      | 2975  |  800   | 3000
    7788  | 20      | 3000  |  800   | 3000
    7902  | 20      | 3000  |  800   | 3000
    7900  | 30      |  950  |  950   | 2850
    7654  | 30      | 1250  |  950   | 2850
    7521  | 30      | 1250  |  950   | 2850
    7844  | 30      | 1500  |  950   | 2850
    7499  | 30      | 1600  |  950   | 2850
    7698  | 30      | 2850  |  950   | 2850
    
  • Example without the KEEP statement.

    EMPNO | DEPTNO  | SAL   | LOWEST | HIGHEST
    7934  | 10      | 1300  | 1300   | 5000
    7782  | 10      | 2450  | 1300   | 5000
    7839  | 10      | 5000  | 1300   | 5000
    7369  | 20      |  800  |  800   | 3000
    7876  | 20      | 1100  |  800   | 3000
    7566  | 20      | 2975  |  800   | 3000
    7788  | 20      | 3000  |  800   | 3000
    7902  | 20      | 3000  |  800   | 3000
    7900  | 30      |  950  |  950   | 2850
    7654  | 30      | 1250  |  950   | 2850
    7521  | 30      | 1250  |  950   | 2850
    7844  | 30      | 1500  |  950   | 2850
    7499  | 30      | 1600  |  950   | 2850
    7698  | 30      | 2850  |  950   | 2850
    

如您所见(并测试)两者输出相同的结果。

MIN(sal) KEEP (DENSE_RANK FIRST ORDER BY sal)表示“按行对行进行排序,并选择那些具有最小sal值的行。如果有更多行具有相同的sal,则启动时的min函数会告诉Oracle选择一个具有最小值的sal。“

在这种情况下,由于DENSE_RANK FIRSTMIN()中的顺序具有相同的列,两者都是相同的,因此我建议不要在此使用KEEP来提高性能的事项。

答案 1 :(得分:1)

Oracle documents its behavior

  

KEEP关键字用于语义清晰度。它有资格   aggregate_function,表示只有FIRST或LAST的值   将返回aggregate_function。