Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/oracle/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
SQL Oracle查询,用于比较公司每个职位的男性和女性工资_Sql_Oracle_Oracle11g - Fatal编程技术网

SQL Oracle查询,用于比较公司每个职位的男性和女性工资

SQL Oracle查询,用于比较公司每个职位的男性和女性工资,sql,oracle,oracle11g,Sql,Oracle,Oracle11g,使用以下列为每个作业ID返回一行: •Job ID •该职位女性平均服务年限,以年为单位,四舍五入至一年的十分之一 •该工作的女性平均工资 •该职位男性平均服务年限,以年为单位,四舍五入至一年的十分之一 •该工作的男性平均工资 •该职位男女平均工资的差异,正数表示女性平均工资较高,负数表示男性平均工资较高 表格 人力资源部员工 Name Null Type -------------- -------- ------------ EMPLOYEE_

使用以下列为每个作业ID返回一行:

•Job ID

该职位女性平均服务年限,以年为单位,四舍五入至一年的十分之一

该工作的女性平均工资

该职位男性平均服务年限,以年为单位,四舍五入至一年的十分之一

该工作的男性平均工资

该职位男女平均工资的差异,正数表示女性平均工资较高,负数表示男性平均工资较高

表格

人力资源部员工

Name           Null     Type         
-------------- -------- ------------ 
EMPLOYEE_ID    NOT NULL NUMBER(6)    
FIRST_NAME              VARCHAR2(20) 
LAST_NAME      NOT NULL VARCHAR2(25) 
EMAIL          NOT NULL VARCHAR2(25) 
PHONE_NUMBER            VARCHAR2(20) 
HIRE_DATE      NOT NULL DATE         
JOB_ID         NOT NULL VARCHAR2(10) 
SALARY                  NUMBER(8,2)  
COMMISSION_PCT          NUMBER(2,2)  
MANAGER_ID              NUMBER(6)    
DEPARTMENT_ID           NUMBER(4)    
GENDER                  CHAR(1) 
到目前为止我拥有的内容但这将为我需要的每个作业id返回一个M&F行M&F列

SELECT gender, job_id, ROUND(AVG(salary),0) as avg_job_salary,
(SELECT ROUND(AVG(salary),0)
FROM hr.employees 
WHERE gender = 'M') AS avg_m_salary, (SELECT ROUND(AVG(salary),0) 
FROM hr.employees 
WHERE gender = 'F') AS avg_f_salary,
ROUND(AVG(days_of_svc/365),1) AS avg_years_svc
FROM (SELECT  job_id, salary, gender, (SYSDATE-hire_date) AS  days_of_svc 
FROM hr.employees)
GROUP BY job_id,gender
ORDER BY job_id, gender;
或版本2

SELECT gender, job_id, ROUND(AVG(salary),0) as avg_job_salary, 
((SELECT ROUND(AVG(salary),0)
FROM hr.employees 
WHERE gender = 'F') - (SELECT ROUND(AVG(salary),0) 
FROM hr.employees 
WHERE gender = 'M')) as diff,
ROUND(AVG(days_of_svc/365),1) AS avg_years_svc
FROM (SELECT  job_id, salary, gender, (SYSDATE-hire_date) AS  days_of_svc 
FROM hr.employees)
GROUP BY job_id,gender
ORDER BY job_id, gender;
示例预期结果行

JOB_ID    F_AVG_LENGTH F_AVG_SAL M_AVG_LENGTH M_AVG_SAL DIFFERENCE
------    ------------ --------- ------------ --------- ----------
MAILCLERK         24.1     48000         23.4     47000       1000
CASHIER            4.6     12000          4.4     13500      -1500

您的预期结果不需要性别作为输出列

因此,您需要将其从select和group by语句中删除:

SELECT job_id, ROUND(AVG(salary),0) as avg_job_salary,
(SELECT ROUND(AVG(salary),0)
FROM hr.employees 
WHERE gender = 'M') AS avg_m_salary, (SELECT ROUND(AVG(salary),0) 
FROM hr.employees 
WHERE gender = 'F') AS avg_f_salary,
ROUND(AVG(days_of_svc/365),1) AS avg_years_svc
FROM (SELECT  job_id, salary, gender, (SYSDATE-hire_date) AS  days_of_svc 
FROM hr.employees)
GROUP BY job_id
ORDER BY job_id;
但是,在subselect中,在这种方法中,同一个表中有太多的凹陷。让我们尝试优化它

编辑:

select job_id,ROUND(AVG(salary),0) avg_job_salary,
round(avg(case when gender='M' then Salary end),0) avg_m_salary,
round(avg(case when gender='F' then Salary end),0) avg_f_salary,
round(avg(case when gender='F' then Salary end),0) - round(avg(case when gender='M' then Salary end),0) diff_in_avg
ROUND(AVG((SYSDATE-HIRE_DATE)/365),1) AS avg_years_svc
from hr.employees group by JOB_ID
order by JOB_ID;
我假设你计算平均年svc的公式已经如预期的那样, 男性和女性候选人不需要区分

编辑2:

枢轴功能可能会有所帮助。这可以帮助您根据男性和女性计数划分平均值

Select job_id,avg_m_salary,avg_f_salary, avg_f_salary - avg_m_salary diff_salary from(
select job_id,salary from hr.employees) PIVOT
(avg(salary) for gender in('M' as avg_m_salary,'F' as avg_f_salary));
啊,我忘了用零除法,所以:

SELECT JOB_ID
, DECODE(F_CNT, 0, 0, ROUND(F_LEN/F_CNT, 1)) F_AVG_LENGTH
, DECODE(F_CNT, 0, 0, F_SAL/F_CNT) F_AVG_SAL
, DECODE(M_CNT, 0, 0, ROUND(M_LEN/M_CNT, 1)) M_AVG_LENGTH 
, DECODE(M_CNT, 0, 0, M_SAL/M_CNT) M_AVG_SAL
, DECODE(M_CNT, 0, 0, M_SAL/M_CNT) - DECODE(F_CNT, 0, 0, F_SAL/F_CNT)
DIFFERENCE FROM (
  SELECT JOB_ID
  , SUM(CASE WHEN gender = 'M' THEN SALARY ELSE 0 END) M_SAL
  , SUM(CASE WHEN gender = 'M' THEN 1 ELSE 0 END) M_CNT 
  , SUM(CASE WHEN gender = 'M' THEN SVC_LEN ELSE 0 END) M_LEN
  , SUM(CASE WHEN gender = 'F' THEN SALARY ELSE 0 END) F_SAL
  , SUM(CASE WHEN gender = 'F' THEN 1 ELSE 0 END) F_CNT 
  , SUM(CASE WHEN gender = 'F' THEN SVC_LEN ELSE 0 END) F_LEN 
  FROM ( 
    SELECT JOB_ID, SALARY, GENDER
    , MONTHS_BETWEEN(SYSDATE, p.HIRE_DATE)/12 svc_len
    FROM EMPLOYEES p
  )
  GROUP BY JOB_ID
) Q;

在我的机器上,我复制了一份
HR.EMPLOYEES
,在我的模式中,我将克隆命名为
HR\u EMPLOYEES
。然后我为
GENDER
添加了一列,因为在我的Oracle副本上,
HR.EMPLOYEES
表没有
GENDER
列。我在专栏中填入了我的最佳猜测,只是为了测试

在Oracle11中,您可以使用PIVOT操作,这使工作更容易。我把平均任期除以365.25,所以用年而不是天来表示。请注意,许多工作要么没有男性,要么没有女性,因此有许多空结果。我想你也希望看到它们——否则它们可能会被忽略

select job_id, round(F_AVG_TENURE_D/365.25, 1)    as f_avg_length, 
               round(F_AVG_SALARY)                as f_avg_salary,
               round(M_AVG_TENURE_D/365.25, 1)    as m_avg_length, 
               round(M_AVG_SALARY)                as m_avg_salary,       
               round(F_AVG_SALARY - M_AVG_SALARY) as avg_sal_diff
from  ( 
        select job_id, gender, sysdate - hire_date as tenure, salary
        from   hr_employees
      )
pivot (avg(tenure) as avg_tenure_d, avg(salary) as avg_salary 
                                                for gender in ('F' as F, 'M' as M))
order by avg_sal_diff desc nulls last, job_id   --  ORDER BY is optional
;
输出

JOB_ID     F_AVG_LENGTH F_AVG_SALARY M_AVG_LENGTH M_AVG_SALARY AVG_SAL_DIFF
---------- ------------ ------------ ------------ ------------ ------------
SH_CLERK           11.2         3511          9.9         2973          538
ST_MAN             12.3         7467         10.3         7000          467
ST_CLERK           10.5         2883         10.8         2743          140
PU_CLERK           11.6         2833           10         2700          133
AD_VP              11.1        17000         15.8        17000            0
SA_REP             10.3         8244         10.6         8471         -228
SA_MAN             10.3        12000         10.9        12333         -333
IT_PROG            10.2         4500         10.5         6600        -2100
AC_ACCOUNT                                   14.4         8300
AC_MGR             14.4        12008
AD_ASST            13.1         4400
AD_PRES                                      13.4        24000
FI_ACCOUNT                                   11.2         7920
FI_MGR             14.2        12008
HR_REP             14.4         6500
MK_MAN                                       12.7        13000
MK_REP             11.2         6000
PR_REP                                       14.4        10000
PU_MAN                                       13.9        11000

19 rows selected.

由于缺乏资源,无法进行测试。不,没关系。我只是想知道为什么您重新发明了avg功能,而不仅仅是使用avg功能?您的HR.EMPLOYEES副本是否有性别专栏?我的没有。(它也没有MAILCLERK的JOB_ID)。我为示例行创建了MAILCLERK,上面的yes性别被视为最后一列,由1个字符M或FAnd表示。您是指数据库附带的标准HR模式吗?我不相信的原因是我有两个不同的Oracle安装,而且在EMPLOYEES表中都没有性别列。经文件确认-见第4.2页顶部。无论如何,您可以通过替换表名来测试我的解决方案-您应该在我使用HR\U EMPLOYEES的地方编写HR.EMPLOYEES。它应该在没有其他变化的情况下工作。确实如此!谢谢我认为这是11g或性别添加到它。
JOB_ID     F_AVG_LENGTH F_AVG_SALARY M_AVG_LENGTH M_AVG_SALARY AVG_SAL_DIFF
---------- ------------ ------------ ------------ ------------ ------------
SH_CLERK           11.2         3511          9.9         2973          538
ST_MAN             12.3         7467         10.3         7000          467
ST_CLERK           10.5         2883         10.8         2743          140
PU_CLERK           11.6         2833           10         2700          133
AD_VP              11.1        17000         15.8        17000            0
SA_REP             10.3         8244         10.6         8471         -228
SA_MAN             10.3        12000         10.9        12333         -333
IT_PROG            10.2         4500         10.5         6600        -2100
AC_ACCOUNT                                   14.4         8300
AC_MGR             14.4        12008
AD_ASST            13.1         4400
AD_PRES                                      13.4        24000
FI_ACCOUNT                                   11.2         7920
FI_MGR             14.2        12008
HR_REP             14.4         6500
MK_MAN                                       12.7        13000
MK_REP             11.2         6000
PR_REP                                       14.4        10000
PU_MAN                                       13.9        11000

19 rows selected.