2013-05-19 81 views
0

由于我不擅长编写SQL查询以便寻求帮助。 我有一个名为程序员,其结构&数据看起来像表:通过SQL查询查找每个lanauges的最高薪水

PNAME,PROF1,PROF2,SALARY 

在小弟弟震数据:

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。

我需要一个查询到每种语言,这意味着我需要为每种语言显示的最高薪水&人名显示收入最高的程序员的名字。 我尽力得到结果,但没有得到答案。 你能帮我吗?

+0

你至少能证明你试过了什么吗?即使它不工作,这样我们会更加兴奋,帮助你:) – Bryan

+0

可能的重复[帮助为要求编写查询的方式](http://stackoverflow.com/questions/2726369/帮助这种方式来编写查询的要求) –

回答

0

虽然我喜欢戈登的回答,您可以用公共表表达式和简单的左做加盟;

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平坦化以分隔行,而左连接基本上找到程序员在哪里不存在具有相同熟练程度的更好的付费程序员。

+1

感谢joachim的回复.....这是我正在寻找的查询....它给我所需的输出....谢谢 – prags

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) 
+0

你可以指向row_number的文档吗?我从来没有听说过它,我很好奇,知道它是如何工作 – Bryan

+0

感谢戈登您的回复... – prags

+0

我使用此查询: - 从row_number(分区由prof1)选择*从程序员萨尔... ...但不能比较prof1和prof2 .....你的查询看起来不错,我会测试它,并让你知道结果....感谢您的帮助.... – prags

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 

注意,这个查询优化,远离最有效的方式来查询您的表。如果可能的话,重新构建您的数据,让程序员,语言和他们的熟练程度在不同的表格上。

一个干净的实现,带有嵌套的子查询。更多查询,但是您通过直接引用查询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