2016-09-22 72 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;