2017-09-02 138 views
-3

在Microsoft SQL Server中,我有一個包含EmployeeID,Category和Amount列的表。我如何只顯示每個員工的金額最高的類別?爲每個實體選擇最大值

數據示例:

EmployeeID Category Amount 
11111  Vacation 4 
11111  Personal 2 
11111  Holiday  3 
22222  Vacation 1 
22222  Personal 3 
22222  Holiday  2 
33333  Personal 5 
33333  Holiday  1 
33333  Vacation 3 
33333  Unspecified 3 

結果:

EmployeeID Category Amount 
11111  Vacation 4 
22222  Personal 3 
33333  Personal 5 
+0

所以你要每名僱員行,每類吧?我問,因爲你的結果不包括'11111'與類別'個人' – Jaya

+0

爲什麼你很少接受答案? – scsimon

+0

Jaya,只有一個類別每個員工有最高金額 –

回答

0

使用EXISTS/NOT EXISTS

select * 
from Employees 
where not exists 
    (select * from Employees as E 
    where E.EmployeeID=Employees.EmployeeID -- join condition 
    and E.Amount>Employees.Amount) -- filter condition 
2

另一種選擇是WITH TIES的子句

Select Top 1 with Ties * 
From YourTable 
Order By Row_Number() over (Partition By EmployeeID Order By Amount Desc) 

返回

enter image description here


或者用ROW_NUMBER()和一個CTE

;with cte as (
Select * 
     ,RN = Row_Number() over (Partition By EmployeeID Order By Amount Desc) 
From YourTable 
) 
Select EmployeeID 
     ,Category 
     ,Amount 
From cte where RN=1 
2

以下是幾個不同的選項。根據可用的索引,它們中的任何一個都可以比另一個更好地執行,所以這三者都值得在您的環境中測試。

SET NOCOUNT ON; 

IF OBJECT_ID('tempdb..#TestData', 'U') IS NOT NULL 
DROP TABLE #TestData; 

CREATE TABLE #TestData (
    EmployeeID INT NOT NULL, 
    Category VARCHAR(20) NOT NULL, 
    Amount MONEY NOT NULL 
    ); 
INSERT #TestData (EmployeeID, Category, Amount) VALUES 
    (11111, 'Vacation ', 4), 
    (11111, 'Personal ', 2), 
    (11111, 'Holiday ', 3), 
    (22222, 'Vacation ', 1), 
    (22222, 'Personal ', 3), 
    (22222, 'Holiday ', 2), 
    (33333, 'Personal ', 5), 
    (33333, 'Holiday ', 1), 
    (33333, 'Vacation ', 3), 
    (33333, 'Unspecified', 3); 

-- add a covering index to improve performance of the various options 
CREATE NONCLUSTERED INDEX ix_TestData ON #TestData (EmployeeID, Amount DESC) INCLUDE (Category); 

------------------------------------------ 

IF OBJECT_ID('tempdb..#Employee', 'U') IS NOT NULL 
DROP TABLE #Employee; 

CREATE TABLE #Employee (
    EmployeeID INT NOT NULL 
    ); 
INSERT #Employee (EmployeeID) VALUES 
    (11111), (22222), (33333); 

-- SELECT * FROM #TestData td; 

--============================================================ 
--============================================================ 

SELECT TOP 1 WITH TIES 
    td.EmployeeID, td.Category, td.Amount 
FROM 
    #TestData td 
ORDER BY 
    ROW_NUMBER() OVER (PARTITION BY td.EmployeeID ORDER BY td.Amount DESC); 

--============================================================ 

SELECT 
    tdt.EmployeeID, tdt.Category, tdt.Amount 
FROM 
    #Employee e 
    CROSS APPLY (
     SELECT TOP 1 
      td.EmployeeID, td.Category, td.Amount 
     FROM 
      #TestData td 
     WHERE 
      e.EmployeeID = td.EmployeeID 
     ORDER BY 
      td.Amount DESC 
     ) tdt; 

--============================================================ 

WITH 
    cte_AddRN AS (
     SELECT 
      td.EmployeeID, td.Category, td.Amount, 
      RN = ROW_NUMBER() OVER (PARTITION BY td.EmployeeID ORDER BY td.Amount DESC) 
     FROM 
      #TestData td 
     ) 
SELECT 
    ar.EmployeeID, ar.Category, ar.Amount 
FROM 
    cte_AddRN ar 
WHERE 
    ar.RN = 1; 

所有3產生相同的結果...

EmployeeID Category    Amount 
----------- -------------------- --------------------- 
11111  Vacation    4.00 
22222  Personal    3.00 
33333  Personal    5.00 

EmployeeID Category    Amount 
----------- -------------------- --------------------- 
11111  Vacation    4.00 
22222  Personal    3.00 
33333  Personal    5.00 

EmployeeID Category    Amount 
----------- -------------------- --------------------- 
11111  Vacation    4.00 
22222  Personal    3.00 
33333  Personal    5.00 
+1

CTE方法偉大的,快速,謝謝,賈森! –

+0

這是我期望成爲冠軍的人,但我之前感到驚訝。我很高興你能工作。 :) –

0
SELECT EmployeeID, Category, Amount 
FROM (select *, ROW_NUMBER() OVER (PARTITION BY EmployeeID 
     ORDER BY EmployeeID as rn ,Amount desc) 
FROM getmaxdata) x WHERE x.rn =1