2017-09-02 19 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

...同じ結果を生みますか?あなたの結果に「Personal」カテゴリの「11111」は含まれていないので、私は尋ねます – Jaya

+0

なぜあなたはあまり答えを受け入れないのですか? – scsimon

+0

Jaya、最高額の従業員1つのカテゴリ –

答えて

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

別のオプションは、TIES句

WITH です210の

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

ここにはいくつかのオプションがあります。利用可能なインデックスに応じて、他のインデックスより優れたパフォーマンスを発揮できるため、3つすべてが貴社の環境でテストする価値があります。

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メソッドはすばらしい、速く、ありがとう、Jason! –

+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 
関連する問題