如何选择支付的2个最高价格

时间:2017-05-19 12:47:46

标签: sql sql-server

这是输入数据。

  Dept            Company                   Code      Payment Amt

Gardeners     Sort:Insurance Carrier        100         20.00
Gardeners     Sort:Insurance Carrier        100         22.00
Gardeners     Sort:Insurance Carrier        100         21.00
Gardeners     Sort:Insurance Carrier        100         20.00
Gardeners     Sort:Insurance Carrier        100         22.00 

我想返回

Sort:Insurance Carrier 100   -  22.00 and 21.00

不是22.00和22.00我担心这个代码会返回22和22,可以说是支付了2个最高价但不是真的。

我有这个SQL

SELECT 
[DEPT], [Sort: Procedure Code] as Code, [Sort: Insurance Carrier], 
SUM(CASE WHEN num = 1 THEN [Pmt Amount] ELSE 0 END) AS [first high], 
SUM(CASE WHEN num = 2 THEN [Pmt Amount] ELSE 0 END) AS [second high] 
FROM 
(
SELECT ROW_NUMBER() OVER(PARTITION BY 
[DEPT], [Sort: Procedure Code], [Sort: Insurance Carrier]
ORDER BY [Pmt Amount] DESC) AS num, 
[DEPT], [Sort: Procedure Code], [Sort: Insurance Carrier], 
[Pmt Amount]
FROM 
[revenuedetail$]
) AS t 
WHERE num IN (1, 2)
GROUP BY [DEPT], [Sort: Procedure Code], [Sort: Insurance Carrier]

3 个答案:

答案 0 :(得分:2)

如果您希望相同的值具有相同的数字,则应使用dense_rank()而不是row_number()。但是你走在正确的轨道上了!

同时将sum()更改为max(),以避免将值与dense_rank()相加。

试试这个:

select 
    [dept]
  , [Sort: Procedure Code] as Code
  , [Sort: Insurance Carrier]
  , max(case when num = 1 then [Pmt Amount] else 0 end) as [first high]
  , max(case when num = 2 then [Pmt Amount] else 0 end) as [second high] 
from (
  select 
      dense_rank() over(
        partition by [dept], [Sort: Procedure Code], [Sort: Insurance Carrier]
        order by [Pmt Amount] desc
        ) as num
    , [dept]
    , [Sort: Procedure Code]
    , [Sort: Insurance Carrier]
    , [Pmt Amount]
  from [revenuedetail$]
  ) as t 
where num in (1, 2)
group by [dept], [Sort: Procedure Code], [Sort: Insurance Carrier]

rextester演示:http://rextester.com/PJCDDC90476

返回:

+-----------+------+-------------------------+------------+-------------+
|   dept    | Code | Sort: Insurance Carrier | first high | second high |
+-----------+------+-------------------------+------------+-------------+
| Gardeners |  100 | Sort:Insurance Carrier  | 22.00      | 21.00       |
+-----------+------+-------------------------+------------+-------------+

答案 1 :(得分:2)

您似乎想要dense_rank()而不是row_number()

SELECT [DEPT], [Sort: Procedure Code] as Code, [Sort: Insurance Carrier],
       SUM(CASE WHEN num = 1 THEN [Pmt Amount] END) AS [first high], 
       SUM(CASE WHEN num = 2 THEN [Pmt Amount] END) AS [second high] 
FROM (SELECT DENSE_RANK() OVER (PARTITION BY [DEPT], [Sort: Procedure Code], [Sort: Insurance Carrier]
                                ORDER BY [Pmt Amount] DESC
                               ) AS num, 
             rd.*
      FROM [revenuedetail$] rd
     ) rd
WHERE num IN (1, 2)
GROUP BY [DEPT], [Sort: Procedure Code], [Sort: Insurance Carrier];

注意:

  • 我删除了ELSE 0。如果没有第二个值,则此版本返回NULL而不是0。我发现更直观(如果这不是您想要的行为,请添加ELSE 0。)
  • 我添加了更有意义的表别名。 rdt更有意义。
  • 我在子查询中使用了rd.*。这实际上缩短了查询并使其更容易修改。
  • 您应该重新考虑您的列名称。所有方括号只会使代码更难编写和阅读。

答案 2 :(得分:0)

如果sql server版本是2012及更高版本,则可以使用Lead():

select Top 1 [DEPT], [Sort: Procedure Code], [Sort: Insurance Carrier],
[Pmt Amount] AS [first high],  
Lead([Pmt Amount],1)over(partition by [DEPT], [Sort: Procedure Code], 
[Sort: Insurance Carrier] ORDER BY [Pmt Amount] DESC)AS [Second high]
from [revenuedetail$] order by [Pmt Amount] desc