【问题标题】:Oracle SQL Partitions and RankOracle SQL 分区和排名
【发布时间】:2017-06-03 04:24:04
【问题描述】:

我希望能够为员工(包括他们工作的部门和经理)的最新项目按生效日期对数据进行分组。这是数据的示例。

PROJ_TBL

+-------------+----------+----------------+
| EMPLOYEE_ID | EFF_DATE | EMPL_PROJECT   |
+-------------+----------+----------------+
| P1441       | 05/21/11 | IMC            |
| P1441       | 09/12/12 | BEEB           |
| P1441       | 09/23/12 | PRUD_FIN_SALES |
+-------------+----------+----------------+

EMPLOYEE_TBL

+-------------+--------------+---------+----------+
| EMPLOYEE_ID | PROJECT_MBR  | DEPT_NM | EFF_DATE |
+-------------+--------------+---------+----------+
| P1441       | BEN DEENEY   | ACCNT   | 02/09/08 |
| P1566       | LAURA FIELDS | ACCNT   | 05/03/10 |
| P2155       | PAUL DAVEY   | ACCNT   | 10/03/10 |
| P1441       | BEN DEENEY   | SALES   | 07/19/12 |
+-------------+--------------+---------+----------+

EMP_DPT_TBL

+-------------+---------------+---------+----------+
| EMPLOYEE_ID | MANAGER       | DEPT_NM | EFF_DATE |
+-------------+---------------+---------+----------+
| P1441       | BOB PAISLEY   | ACCNT   | 02/09/08 |
| P1441       | LINDA HARDY   | SALES   | 07/19/12 |
+-------------+---------------+---------+----------+

我对分区的使用不是很熟悉。我希望能够使用它来组合信息以获取EMPLOYEE_IDP1441 的当前数据。所需的输出是:

+-------------+---------+--------------+----------------+
| EMPLOYEE_ID | DEPT_NM | MANAGER      | PROJECT        |
+-------------+---------+--------------+----------------+
| P1441       | SALES   | LINDA HARDY  | PRUD_FIN_SALES |
+-------------+---------+--------------+----------------+

我能够为各个表获取正确的当前记录,但是将结果组合起来生成我想要的结果是有问题的。以下是查询...

-- Current Project
SELECT EMPL_PROJECT,
       EMPLOYEE_ID,
       EFF_DT
FROM   ( SELECT EMPL_PROJECT,
                EMPLOYEE_ID,
                EFF_DT,
                RANK() OVER ( PARTITION BY EMPLOYEE_ID
                              ORDER BY EFF_DT DESC) AS rk1
        FROM    PROJ_TBL ) t
WHERE  rk1 = 1

-- Current Department
SELECT DEPT_NM,
       EMPLOYEE_ID,
       EFF_DT
FROM   ( SELECT DEPT_NM,
                EMPLOYEE_ID,
                EFF_DT,
                RANK() OVER ( PARTITION BY EMPLOYEE_ID
                              ORDER BY EFF_DT DESC ) AS rk2 
         FROM   EMPLOYEE_TBL ) t
WHERE  rk2 = 1

-- Current Manager
SELECT MANAGER,
       EMPLOYEE_ID,
       EFF_DT
FROM   ( SELECT MANAGER,
                EMPLOYEE_ID,
                EFF_DT,
                RANK() OVER ( PARTITION BY EMPLOYEE_ID
                              ORDER BY EFF_DT DESC ) AS rk3
         FROM   EMP_DPT_TBL ) t
WHERE  rk3 = 1

如何使用EMPLOYEE_ID 将这些组合成一个查询来生成报告?

【问题讨论】:

  • 与您的问题完全无关,但是为什么您在employee_tbl 中同时存储员工的ID 和他或她的姓名?更好的(规范化)设计是有一个不同的表,其中员工 ID 作为主键(所以,没有重复!),对于每个 ID,员工的姓名。这实际上被称为“employee_tbl”。然后,您在第二张表中显示的是员工分配到不同部门的历史表;此历史表应该只有员工 ID,而不是姓名 - 部门也应相同(仅包括部门 ID 并有单独的 DEPARTMENTS_TBL)。

标签: sql oracle window-functions


【解决方案1】:

这就是你要找的吗?

SELECT DISTINCT
  EMPLOYEE_ID
  ,first_value(dept.dept_nm) over (partition by dept.employee_id order by dept.eff_date desc) as DEPT_NM
  ,first_value(dept.manager) over (partition by dept.employee_id order by dept.eff_date desc) as MANAGER
  ,first_value(proj.EMPL_PROJECT) over (partition by proj.employee_id order by proj.eff_date desc) as PROJECT
FROM
  EMPLOYEE_TBL emp
  INNER JOIN PROJ_TBL proj ON emp.EMPLOYEE_ID = proj.EMPLOYEE_ID
  INNER JOIN EMP_DPT_TBL dept on emp.EMPLOYEE_ID = dept.EMPLOYEE_ID

【讨论】:

  • 我的错,它似乎工作让我再做一些检查
猜你喜欢
  • 1970-01-01
  • 2014-11-01
  • 1970-01-01
  • 1970-01-01
  • 2014-05-20
  • 2021-05-05
  • 1970-01-01
  • 1970-01-01
  • 2011-11-15
相关资源
最近更新 更多