SQL查询以查找每种语言的最高工资

时间:2013-05-19 17:32:58

标签: sql sql-server greatest-n-per-group

因为我不是编写SQL查询的专家所以需要帮助。 我有一个名为programmer的表,其结构和数据看起来像:

PNAME,PROF1,PROF2,SALARY

在prof1数据中是:

  

PASCAL,CLIPPER,COBOL,CPP,COBOL,PASCAL,汇编,PASCAL,BASIC,C,PASCAL,FOXPRO。

在prof2数据中:

  

BASIC,COBOL,DBASE,DBASE,ORACLE,DBASE,CLIPPER,C,DBASE,COBOL,汇编,BASIC,C

在薪资数据中是:

  

3200,2800,3000,2900,4500,2500,2800,3000,3200,2500,3600,3700,3500。

我需要一个查询来显示每种语言的最高薪酬程序员的名字,这意味着我需要显示最高工资和最高工资。每种语言的人名。 我尽力得到结果,但没有得到答案。 你能救我吗?

3 个答案:

答案 0 :(得分:0)

函数row_number()是最好的方法。

select t.*
from (select t.*,
             row_number() over (partition by language order by salary desc) as seqnum
      from t
     ) t
where seqnum = 1;

如果有多个程序员具有相同的薪水,则返回其中一个。如果您想要所有这些内容,请使用dense_rank()代替row_number()

在重新阅读查询时,我认为“语言”可能位于prof1prof2。这使查询复杂化。可能最简单的方法是使用窗口函数来获取每个函数的最大值,然后比较工资:

select t.*
from (select t.*,
             max(salary) over (partition by prof1) as max1,
             max(salary) over (partition by prof2) as max2
      from t
     ) t
where (salary = max1 and max1 >= max2) or
      (salary = max2 and max2 >= max1)

答案 1 :(得分:0)

虽然我喜欢Gordon的回答,但您可以使用公用表表达式和简单的左连接来完成;

WITH cte AS (
  SELECT PNAME, SALARY, PROF1 PROF FROM programmer
  UNION 
  SELECT PNAME, SALARY, PROF2      FROM programmer
)
SELECT p1.PNAME, p1.PROF, p1.SALARY
FROM cte p1
LEFT JOIN cte p2
  ON p1.PROF = p2.PROF AND p1.SALARY < p2.SALARY
WHERE p2.PNAME IS NULL;

EDIT: An SQLfiddle for testing

联合会将PROF1和PROF2展平为单独的行,而左联接基本上找到程序员,其中没有更好的付费程序员具有相同的熟练程度。

答案 2 :(得分:0)

您的数据集标准化程度很低,有时会出现,但出于性能原因值得修改。

要获得您正在寻找的查询,您需要派生一组所有不同的语言,提取最大工资的标识符,然后使用该工资引用程序员。有多种方法可以实现这一点,最简单的方法可能是三个子查询。

SELECT 
  lang.prof,
  (
    SELECT TOP 1 pname
    FROM programmer
    WHERE prof1 = lang.prof OR prof2 = lang.prof
    ORDER BY salary DESC
  ) as Name,
  (
    SELECT MAX(Salary)
    FROM programmer
    WHERE prof1 = lang.prof OR prof2 = lang.prof
  ) as MaxSalary
FROM (
  SELECT prof1 as prof FROM programmer 
  UNION
  SELECT prof2 as prof FROM programmer 
) AS lang

请注意,此查询 NOT 已优化,并且远非查询表的最有效方式。如果可能,重新构建数据,使程序员,语言及其熟练程度在不同的表上。

带有嵌套子查询的更干净的实现。更多查询,但您通过直接引用查询Programmer并可以添加任意行。

SELECT 
  Lang.prof,
  P.PName,
  P.Salary
FROM 
(
    SELECT LL.prof, MAX(sP.salary) as MaxSalary
    (
      SELECT prof1 as prof FROM programmer 
      UNION
      SELECT prof2 as prof FROM programmer 
    ) as LL
    INNER JOIN programer sP
        ON LL.prof = sP.prof1 OR LL.prof = sP.prof2
    GROUP BY LL.prof
) as Lang
INNER JOIN programmer P
  ON (Lang.prof = P.prof1 OR P.prof2)
  AND lang.MaxSalary = P.salary