我有桌子
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
答案 0 :(得分: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
方法实际上可能更快。
答案 1 :(得分: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
相同的输出。
答案 2 :(得分:1)
使用Partition By和With Statement
@fields(key = "sample")
static public int data = 2;
答案 3 :(得分: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
)
)
答案 4 :(得分:0)
试试这个
SELECT * FROM (选择 user_id,薪水 ,dense_rank()OVER(由user_id ORDER BY salary desc分区)作为排名 来自薪水)a 通过a.user_id
命令a.ranking&lt; = 2答案 5 :(得分: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
答案 6 :(得分: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;