2013-05-19 121 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