2016-09-22 38 views
4

我有表如何爲每個人選擇最高的N個薪水?

user_id salary month 
1  100 1 
1  150 2 
1  200 3 
1  180 4 
1  140 5 
2  10  1 
2  40  2 
2  20  3 
2  15  4 
2  45  5 

我想選擇前2的薪水每個人。

我嘗試瞭解交叉應用。看起來像我發明的任務符合交叉應用。

現在我有以下查詢

select distinct(s.user_id) from Salary s 
cross apply (
    select top 2 * from Salary sal 
    order by sal.salary desc 
)sal 

的樣子,我從預期的結果遠遠不夠。

預期的結果:

1 180 
1 200 
2 40 
2 45 
+2

喜歡這個? http://stackoverflow.com/questions/176964/select-top-10-records-for-each-category – DavidG

回答

3

您可以使用OUTER APPLY與TOP 2:

SELECT DISTINCT 
      y.[user_id], 
      d.salary, 
      d.[month] 
FROM YourTable y 
OUTER APPLY(
    SELECT TOP 2 * 
    FROM YourTable 
    WHERE y.[user_id] = [user_id] 
    ORDER BY [user_id], salary DESC 
    ) as d 
ORDER BY [user_id], salary DESC 

返回結果:

user_id salary month 
1  200  3 
1  180  4 
2  45  5 
2  40  2 

另一種方式:

;WITH cte AS (
SELECT *, 
     ROW_NUMBER() OVER (PARTITION BY [user_id] ORDER BY salary DESC) as rn 
FROM YourTable 
) 

SELECT [user_id], salary, [month] 
FROM cte 
WHERE rn <= 2 

相同的輸出。

3

你接近,只是沒有選擇正確的價值觀:

select sal.* 
from (select distinct s.user_id from Salary s) s cross apply 
    (select top 2 sal.* 
     from Salary sal 
     order by sal.salary desc 
    ) sal; 

注意,這樣做的一個典型的方法就是使用row_numbers()。我認爲apply方法在某些情況下實際上可能會更快。

+0

**從工資s.sal ** - 這是不正確的語法 – gstackoverflow

+0

你能簡要解釋查詢的結構? – gstackoverflow

+0

您的查詢不起作用 – gstackoverflow

1

使用分區中,並與聲明

Declare @SeriesNo INT=2 

;With X AS 
(
    SELECT 
     UserId, 
     Salary,   
     Month_Name, 
     ROW_NUMBER() OVER(PARTITION BY UserId Order BY Salary Desc) AS PartNo 
    FROM @tblTest  
) 
SELECT 
    UserId, 
    Salary,   
    Month_Name 
FROM X 
WHERE X.PartNo <[email protected] 
0

試試這個。

SELECT s.user_id, s.salary 
FROM SALARY s 
WHERE s.salary = 
       (
       SELEACT MAX(ss.salary) 
       FROM SALARY ss 
       WHERE s.user_id = ss.user_id 
      ) 
OR s.salary = 
       (
       SELEACT MAX(ss.salary) 
       FROM SALARY ss 
       WHERE s.user_id = ss.user_id 
       AND ss.salary < 
           (
           SELEACT MAX(sss.salary) 
           FROM SALARY sss 
           WHERE s.user_id = sss.user_id 
          ) 
      ) 
0

試試這個

SELECT * FROM (SELECT USER_ID,工資 ,DENSE_RANK()OVER(由USER_ID ORDER BY分區工資DESC)作爲排名 自於工資的)一個 WHERE a.ranking < = 2以便通過a.user_id

0

可以通過使用ROW_NUMBER()

;WITH cte 
AS (SELECT 
    *, ROW_NUMBER() OVER (PARTITION BY userid ORDER BY salary DESC) rn 
FROM salaries) 
SELECT 
    userid, 
    salary 
FROM cte 
WHERE rn <= 2 
使用查詢
0

您也可以使用下面的查詢。

DECLARE @TopFilter AS TINYINT = 2; 
SELECT TOP (1) WITH TIES user_id, salary 
FROM Salary 
ORDER BY (ROW_NUMBER() OVER(PARTITION BY user_id ORDER BY salary DESC) - 1)/@TopFilter + 1; 
相關問題