如何从每个部门仅获得一份最低工资雇员的记录? DB2

问题描述 投票:1回答:1

我几乎刚开始使用数据库语言,所以我对JOIN,PARTITION和ETC一无所知。但这是我到目前为止所拥有的。

我尝试过的事情:

SELECT MIN(SALARY) AS "MIN SALARY", WORKING.DID, ENAME
  FROM DEPARTMENT, EMPLOYEE, WORKING
 WHERE WORKING.EID = EMPLOYEE.EID
 GROUP BY WORKING.DID, ENAME;
Result:
 MIN SALARY DID ENAME
 ---------- --- ------
      10000 101 Dustin
      15000 102 Bob
      20000 102 David
      10000 102 Dustin
      10000 103 Alex
       8000 103 Alice
       7000 103 Mike

我想要的是:

 MIN SALARY DID ENAME
 ---------- --- ------
      10000 101 Dustin
      10000 102 Dustin
       7000 103 Mike

表结构:

CREATE TABLE EMPLOYEE (
    EID INTEGER NOT NULL,
    ENAME VARCHAR(25),
    SALARY DECIMAL,
    PRIMARY KEY (EID)
);

CREATE TABLE WORKING (
    EID INTEGER NOT NULL,
    DID INTEGER NOT NULL,
    STIME DATE,
    FOREIGN KEY (EID) REFERENCES EMPLOYEE (EID),
    FOREIGN KEY (DID) REFERENCES DEPARTMENT (DID),
    PRIMARY KEY (EID, DID)
);

CREATE TABLE DEPARTMENT (
    DID INTEGER NOT NULL,
    DNAME VARCHAR(10),
    DADDRESS VARCHAR(20),
    PRIMARY KEY (DID)
);

ER Diagram

sql db2 greatest-n-per-group
1个回答
1
投票

您可能更喜欢使用在线分析处理(OLAP)功能,例如DENSE_RANK()来轻松获得所需的结果

SELECT Q.SALARY, Q.DID, Q.ENAME 
  FROM
  (
   SELECT E.SALARY, W.DID, E.ENAME,
          DENSE_RANK() OVER (PARTITION BY W.DID ORDER BY E.SALARY) AS DR
     FROM WORKING W
     JOIN DEPARTMENT D
       ON D.DID = W.EID
     JOIN EMPLOYEE E
       ON E.EID = W.EID
   )
  WHERE DR = 1

其中使用显式JOIN语法,将具有逗号分隔的表的语法视为已过时的语法。使用(INNERJOIN足以满足您的情况,而在某些情况下可能需要OUTERLEFT-RIGHTFULLJOIN s。

在分析函数中,PARTITION子句用于表示GROUPING BY criteira。基于ORDER的升序salary,我们将通过DENSE_RANK()函数得出的值等于1的结果得到最小的过滤条件。

通过使用这种方法,即使每个部门有一个以上的人员,您也可以使所有雇员获得最低工资。

此外,最好使用表名的别名(或表名中包含的两个或三个字符,这取决于首字母的公共字符)来别名化表,以限定查询中的列,而不是使用全名。

© www.soinside.com 2019 - 2024. All rights reserved.