![](/img/trans.png)
[英]How to compare the column values of the max and min dates of a group of rows in Oracle?
[英]Getting values relating to the max and min rows in Oracle
在 Oracle 11g 中,我們需要能夠查詢表以從某個組中具有最高和最低值的行中提取信息。 例如使用 EMP 表,我們想找到每個部門中薪水最高的人的姓名和薪水最低的人的姓名
DEPTNO MAX_SAL MAX_EARNER MIN_SAL MIN_EARNER
-------------------------------------------------------
10 5000 KING 1300 MILLER
20 3000 FORD 2975 JONES
etc
(如果有兩個或更多員工的薪水最高或最低,我們希望始終按字母順序返回第一個)。
上一篇文章討論了如何僅獲取最大值而不是最大值和最小值的值。
基於上面的鏈接,我們目前有一個不整潔的解決方案,然后應用后續查詢,但性能對我們很重要。 我預測一個好的解決方案還需要分析函數,可能還需要一個 pivot 來將多行合並為單行。
非常感謝任何幫助! 理查德
這很容易用解析函數解決。 如您所見,有兩名員工在 DEPT 20 中獲得最高工資; 這是一個重要的細節,因為此類問題的一些常見解決方案會忽略該信息。
SQL> select ename
2 , deptno
3 , sal
4 from (
5 select ename
6 , deptno
7 , sal
8 , max (sal) over (partition by deptno) max_sal
9 , min (sal) over (partition by deptno) min_sal
10 from emp
11 )
12 where sal = max_sal
13 or sal = min_sal
14 order by deptno, sal
15 /
ENAME DEPTNO SAL
---------- ---------- ----------
KISHORE 10 1300
SCHNEIDER 10 5000
CLARKE 20 800
RIGBY 20 3000
GASPAROTTO 20 3000
HALL 30 950
LIRA 30 3750
TRICHLER 50 3500
FEUERSTEIN 50 4500
9 rows selected.
SQL>
糟糕,我錯過了有關結果格式的重要細節。 我的數據不符合要求的 output,因為有兩名員工獲得最高工資。 因此,我承認這個查詢有點尷尬,它為我們提供了所需的布局。 員工姓名上的 MIN() 返回字母順序:
SQL> select
2 deptno
3 , max (case when sal = min_sal then min_sal else null end ) as min_sal
4 , min (case when sal = min_sal then ename else null end ) as min_name
5 , max (case when sal = max_sal then max_sal else null end ) as max_sal
6 , min (case when sal = max_sal then ename else null end ) as max_name
7 from (
8 select ename
9 , deptno
10 , sal
11 , max (sal) over (partition by deptno) max_sal
12 , min (sal) over (partition by deptno) min_sal
13 from emp
14 )
15 where sal = max_sal
16 or sal = min_sal
17 group by deptno
18 order by deptno
19 /
DEPTNO MIN_SAL MIN_NAME MAX_SAL MAX_NAME
---------- ---------- ---------- ---------- ----------
10 1300 KISHORE 5000 SCHNEIDER
20 800 CLARKE 3000 GASPAROTTO
30 950 HALL 3750 LIRA
50 3500 TRICHLER 4500 FEUERSTEIN
SQL>
我不喜歡這個解決方案。 大多數數據集都會包含這樣的沖突,我們需要承認它們。 根據一些不相關的標准過濾結果以適應 Procrustean 報告布局是誤導性的。 我更喜歡反映整個數據集的報告布局。 最終,它取決於查詢服務的業務目的。 而且,當然,客戶永遠是對的 8-)
您可以使用以下查詢
SELECT
dept,
max_sal,
(SELECT emp_name FROM emp WHERE salary = max_sal AND rownum =1) max_earner,
min_sal,
(SELECT emp_name FROM emp WHERE salary = min_sal AND rownum =1) min_earner
FROM
(SELECT
dept,
MAX(salary) max_sal,
MIN(salary) min_sal
FROM emp
GROUP BY dept);
假設您的表格如下所示:
CREATE TABLE emp
(
dept NUMBER,
emp_name VARCHAR2(20 BYTE),
salary NUMBER
);
更新
為了滿足您的其他要求“如果有兩個或更多員工的薪水最高或最低,我們希望始終按字母順序返回第一個”,您可以稍微調整查詢如下(我確定有 scope這里的改進):
SELECT
dept,
max_sal,
(select emp_name from (SELECT * FROM emp order by emp_name asc) WHERE salary = max_sal AND rownum =1) max_earner,
min_sal,
(select emp_name from (SELECT * FROM emp order by emp_name asc) WHERE salary = min_sal AND rownum =1) min_earner
FROM
(SELECT
dept,
MAX(salary) max_sal,
MIN(salary) min_sal
FROM emp
GROUP BY dept);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.