使用Aggregate和Max函数

时间:2013-04-18 15:16:08

标签: sql sql-server-2008 case aggregate-functions

我在SQL Server中使用以下查询时遇到问题。

SELECT  
        emp_id= CASE employee_id
        WHEN ''
            THEN RTRIM(last_name) + '_' + RTRIM(first_name)
            + '_' + RTRIM(gender) + '_'
            + RTRIM(race_ethnicity_code) + '_'
            + RTRIM(high_degree_code) + '_' + RTRIM(position_code) + '_'
            + RTRIM(assignment_code)
            ELSE employee_id
            END , 
        last_name, first_name, 
        assign_perc, 
            assignment_num,
        CAST((total_salary)AS NUMERIC (18,2))* CAST((assign_perc) AS NUMERIC (18,2)) AS salary,
        total_salary
FROM employee 
ORDER BY last_name, first_name, district_name

我的脚本是一个简单的列提取,当它为null时,通过emp_id的case语句创建一个唯一键。我遇到的问题是,当该人具有多个分配时,将assign_perc与total_Salary相乘,并且当该销售人员仅列出一次时获取最大工资。例如 - 我的预期结果:

enter image description here

约翰史密斯只是一名兼职工作者,其中一项任务只被列出一次,因此他的assign_perc将小于1但我仍需要最高工资而不是总工资(assign_perc * total_salary)。谢谢你的帮助。

1 个答案:

答案 0 :(得分:1)

如上所述,由于您需要使用CASE语句来确定虚拟employee_id,因此过于混乱。如果您可以将此CASE语句重构为udf,或者将结果存储在表中,那么它将更简单 更简单

为了澄清这将要做什么 - 您希望在包含每位员工计数的表上加入employee表。计数表如下所示:

SELECT employee_id, COUNT(*) AS employee_count
FROM employee
GROUP BY employee_id

将它们连接在一起看起来像这样:

SELECT ...
FROM employee
JOIN (SELECT employee_id, COUNT(*) AS employee_count
      FROM employee
      GROUP BY employee_id) ec
ON employee.employee_id = ec.employee_id

您的计算工资现在将变为:

        CASE 
            WHEN ec.employee_count > 1 
                THEN CAST((total_salary)AS NUMERIC (18,2))* CAST((assign_perc) AS NUMERIC (18,2)) 
            ELSE total_salary 
        END AS salary,

这是完整的查询代替monstrous CASE语句代替'employee_id':

SELECT  
        CASE employee.employee_id
        WHEN ''
            THEN RTRIM(last_name) + '_' + RTRIM(first_name)
            + '_' + RTRIM(gender) + '_'
            + RTRIM(race_ethnicity_code) + '_'
            + RTRIM(high_degree_code) + '_' + RTRIM(position_code) + '_'
            + RTRIM(assignment_code)
            ELSE employee.employee_id
            END AS emp_id, 
        last_name, first_name, 
        assign_perc, 
        assignment_num,
        CASE 
            WHEN ec.employee_count > 1 
                THEN CAST((total_salary)AS NUMERIC (18,2))* CAST((assign_perc) AS NUMERIC (18,2)) 
            ELSE total_salary 
        END AS salary,
        total_salary
FROM employee
JOIN (SELECT CASE employee.employee_id
        WHEN ''
            THEN RTRIM(last_name) + '_' + RTRIM(first_name)
            + '_' + RTRIM(gender) + '_'
            + RTRIM(race_ethnicity_code) + '_'
            + RTRIM(high_degree_code) + '_' + RTRIM(position_code) + '_'
            + RTRIM(assignment_code)
            ELSE employee.employee_id
            END AS employee_id, COUNT(*) employee_count 
      FROM employee
      GROUP BY CASE employee.employee_id
        WHEN ''
            THEN RTRIM(last_name) + '_' + RTRIM(first_name)
            + '_' + RTRIM(gender) + '_'
            + RTRIM(race_ethnicity_code) + '_'
            + RTRIM(high_degree_code) + '_' + RTRIM(position_code) + '_'
            + RTRIM(assignment_code)
            ELSE employee.employee_id
            END) ec 
  ON CASE employee.employee_id
        WHEN ''
            THEN RTRIM(last_name) + '_' + RTRIM(first_name)
            + '_' + RTRIM(gender) + '_'
            + RTRIM(race_ethnicity_code) + '_'
            + RTRIM(high_degree_code) + '_' + RTRIM(position_code) + '_'
            + RTRIM(assignment_code)
            ELSE employee.employee_id
            END = ec.employee_id
ORDER BY last_name, first_name, district_name