使用前 N 名员工
Using top N Employees
我需要一个查询,以根据工作时间获取特定月份在每个项目上工作的前 N 名员工。而且我一直需要相同的查询(不指定月份)。
我首先得到两个提示 提示:使用替换变量提示用户输入 N 和月份的值。
第二个提示:使用排名分析功能。如果两个员工并列,他们应该获得相同的等级。
现在我有这个未完成的解决方案,不确定我是否应该完成它:
SELECT BSR_PROJ.PROJECT_NAME,
BSR_TM.FNAME || ' ' || BSR_TM.MNAME || ' ' || BSR_TM.LNAME EMPLOYEE_NAME,
BSR_TRD.WORK_ITEM_DATE,
RANK() OVER (PARTITION BY BSR_PROJ.PROJECT_NAME ORDER BY BSR_TRD.WORK_ITEM_DATE ASC) EMPRANK
FROM BSR_TEAM_REPORT_DETAILS BSR_TRD,
BSR_PROJECTS BSR_PROJ,
BSR_TEAM_MEMBERS BSR_TM
WHERE BSR_TRD.BSR_TEAM_RES_ID = BSR_TM.ID
AND BSR_TRD.BSR_PRJ_ID = BSR_PROJ.ID
;
您需要在分析函数中包含月份,因为排名是按每个项目每月计算的;使用月份格式掩码截断日期是实现此目的的简单方法。
您还需要在投影中包括截断的月份,以便对其进行过滤。我选择以 2015-12 的格式显示月份。您可能希望以不同的方式显示它。
您的查询将为所有分配的所有员工生成整组排名。您需要一个外部查询来应用过滤要求。我的方案是使用SQL加替换变量而不是绑定变量,但是原理是一样的:
select distinct project_name
, employee_name
from (
SELECT BSR_PROJ.PROJECT_NAME,
BSR_TM.FNAME || ' ' || BSR_TM.MNAME || ' ' || BSR_TM.LNAME EMPLOYEE_NAME,
to_char(trunc(bsr_trd.work_item_date, 'MM'), 'yyyy-mm') as project_month,
RANK() OVER (PARTITION BY BSR_PROJ.PROJECT_NAME,
trunc(bsr_trd.work_item_date, 'MM')
ORDER BY BSR_TRD.WORK_ITEM_DATE ASC) EMPRANK
FROM BSR_TEAM_REPORT_DETAILS BSR_TRD,
BSR_PROJECTS BSR_PROJ,
BSR_TEAM_MEMBERS BSR_TM
WHERE BSR_TRD.BSR_TEAM_RES_ID = BSR_TM.ID
AND BSR_TRD.BSR_PRJ_ID = BSR_PROJ.ID
)
where project_month = '&proj_month'
and emprank <= &rnk;
我找到的答案如下:
SELECT *
FROM (SELECT RANK ()
OVER (PARTITION BY PROJ_NAME ORDER BY WORKING_HOURS DESC)
AS EMPRANK,
PROJ_NAME,
EMPLOYEE_NAME,
WORKING_HOURS
FROM ( SELECT BSR_PROJ.PROJECT_NAME AS PROJ_NAME,
BSR_TM.FNAME
|| ' '
|| BSR_TM.MNAME
|| ' '
|| BSR_TM.LNAME
EMPLOYEE_NAME,
SUM (WORK_ITEM_CONSUMED_HOURS) AS WORKING_HOURS
FROM BSR_TEAM_REPORT_DETAILS BSR_TRD,
BSR_PROJECTS BSR_PROJ,
BSR_TEAM_MEMBERS BSR_TM
WHERE BSR_TRD.BSR_TEAM_RES_ID = BSR_TM.ID
AND BSR_TRD.BSR_PRJ_ID = BSR_PROJ.ID
AND TO_CHAR (TRUNC (BSR_TRD.WORK_ITEM_DATE, 'MM'),
'YYYY-MM') = '&PROJ_MONTH'
GROUP BY BSR_PROJ.PROJECT_NAME,
BSR_TM.FNAME
|| ' '
|| BSR_TM.MNAME
|| ' '
|| BSR_TM.LNAME)) INNER_TABLE
WHERE EMPRANK <= &RNK;
我需要一个查询,以根据工作时间获取特定月份在每个项目上工作的前 N 名员工。而且我一直需要相同的查询(不指定月份)。
我首先得到两个提示 提示:使用替换变量提示用户输入 N 和月份的值。 第二个提示:使用排名分析功能。如果两个员工并列,他们应该获得相同的等级。
现在我有这个未完成的解决方案,不确定我是否应该完成它:
SELECT BSR_PROJ.PROJECT_NAME,
BSR_TM.FNAME || ' ' || BSR_TM.MNAME || ' ' || BSR_TM.LNAME EMPLOYEE_NAME,
BSR_TRD.WORK_ITEM_DATE,
RANK() OVER (PARTITION BY BSR_PROJ.PROJECT_NAME ORDER BY BSR_TRD.WORK_ITEM_DATE ASC) EMPRANK
FROM BSR_TEAM_REPORT_DETAILS BSR_TRD,
BSR_PROJECTS BSR_PROJ,
BSR_TEAM_MEMBERS BSR_TM
WHERE BSR_TRD.BSR_TEAM_RES_ID = BSR_TM.ID
AND BSR_TRD.BSR_PRJ_ID = BSR_PROJ.ID
;
您需要在分析函数中包含月份,因为排名是按每个项目每月计算的;使用月份格式掩码截断日期是实现此目的的简单方法。
您还需要在投影中包括截断的月份,以便对其进行过滤。我选择以 2015-12 的格式显示月份。您可能希望以不同的方式显示它。
您的查询将为所有分配的所有员工生成整组排名。您需要一个外部查询来应用过滤要求。我的方案是使用SQL加替换变量而不是绑定变量,但是原理是一样的:
select distinct project_name
, employee_name
from (
SELECT BSR_PROJ.PROJECT_NAME,
BSR_TM.FNAME || ' ' || BSR_TM.MNAME || ' ' || BSR_TM.LNAME EMPLOYEE_NAME,
to_char(trunc(bsr_trd.work_item_date, 'MM'), 'yyyy-mm') as project_month,
RANK() OVER (PARTITION BY BSR_PROJ.PROJECT_NAME,
trunc(bsr_trd.work_item_date, 'MM')
ORDER BY BSR_TRD.WORK_ITEM_DATE ASC) EMPRANK
FROM BSR_TEAM_REPORT_DETAILS BSR_TRD,
BSR_PROJECTS BSR_PROJ,
BSR_TEAM_MEMBERS BSR_TM
WHERE BSR_TRD.BSR_TEAM_RES_ID = BSR_TM.ID
AND BSR_TRD.BSR_PRJ_ID = BSR_PROJ.ID
)
where project_month = '&proj_month'
and emprank <= &rnk;
我找到的答案如下:
SELECT *
FROM (SELECT RANK ()
OVER (PARTITION BY PROJ_NAME ORDER BY WORKING_HOURS DESC)
AS EMPRANK,
PROJ_NAME,
EMPLOYEE_NAME,
WORKING_HOURS
FROM ( SELECT BSR_PROJ.PROJECT_NAME AS PROJ_NAME,
BSR_TM.FNAME
|| ' '
|| BSR_TM.MNAME
|| ' '
|| BSR_TM.LNAME
EMPLOYEE_NAME,
SUM (WORK_ITEM_CONSUMED_HOURS) AS WORKING_HOURS
FROM BSR_TEAM_REPORT_DETAILS BSR_TRD,
BSR_PROJECTS BSR_PROJ,
BSR_TEAM_MEMBERS BSR_TM
WHERE BSR_TRD.BSR_TEAM_RES_ID = BSR_TM.ID
AND BSR_TRD.BSR_PRJ_ID = BSR_PROJ.ID
AND TO_CHAR (TRUNC (BSR_TRD.WORK_ITEM_DATE, 'MM'),
'YYYY-MM') = '&PROJ_MONTH'
GROUP BY BSR_PROJ.PROJECT_NAME,
BSR_TM.FNAME
|| ' '
|| BSR_TM.MNAME
|| ' '
|| BSR_TM.LNAME)) INNER_TABLE
WHERE EMPRANK <= &RNK;