在一行中选择特定列的最大值和最小值以及相关列

时间:2018-01-31 16:52:50

标签: sql sql-server tsql

我有下表。

ID  Duration    Count   A           Probability
5   16          0.29    200001      0.000641
5   15          0.71    200000      0.000589
6   14          0.7     250000      0.001319
6   13          0.3      250001     0.001148

我想选择最大和最小持续时间及其相应的列,因为它在一行中具有标识。

我想要的输出是

ID  MinDuration MaxDuration CounforMinD   CounfoMaxD   AforMinD AforMaxD  ..    
5   15              16         0.71          0.29        200000  200001
6   13              14         0.3           0.7         250001  250000

我怎样才能实现这一目标......

3 个答案:

答案 0 :(得分:1)

不幸的是,SQL并不支持first_value()作为聚合函数。所以一种方法是连接和聚合:

select t.id, tt.mind, tt.maxd,
       max(case when t.duration = tt.mind then t.count end) as cnt_at_mind,
       max(case when t.duration = tt.maxd then t.count end) as cnt_at_maxd
from t join
     (select t.id, min(duration) as mind, max(duration) as maxd
      from t
      group by t.id
     ) tt
     on t.id = tt.id
group by t.id, tt.mind, tt.maxd;

实际上,更简单的方法是:

select t.id, t.mind, t.maxd,
       max(case when t.duration = t.mind then t.count end) as cnt_at_mind,
       max(case when t.duration = t.maxd then t.count end) as cnt_at_maxd
from (select t.*, min(duration) over (partition by id) as mind,
             max(duration) over (partition by id) as maxd
      from t
     ) t
group by t.id, tt.mind, tt.maxd;

答案 1 :(得分:0)

-- temprary table to test
create table #t (
    ID int not null,
    Duration int not null,
    Count float not null,
    A int not null,
    Probability float not null
)

insert into #t
values 
    (5, 16, 0.29, 200001, 0.000641),
    (5, 15, 0.71, 200000, 0.000589),
    (6, 14, 0.7, 250000, 0.001319),
    (6, 13, 0.3, 250001, 0.001148)

-- query to select
select t1.*, CounforMinD = t2.Count, CounforMaxD = t3.Count, AforMinD = t2.A, AforMaxD = t3.A, ProbforMinD = t2.Probability, ProbforMaxD = t3.Probability
from (  select t.ID, MinDuration = min(t.duration), MaxDuration = max(t.duration)
        from #t t
        group by t.ID) t1
    join #t t2 on
        t2.id = t1.ID and
        t2.Duration = MinDuration
    join #t t3 on
        t3.id = t1.ID and
        t3.Duration = MaxDuration


drop table #t

答案 2 :(得分:0)

我认为这就是你要找的东西

with cte as 
(   select * 
         , ROW_NUMBER() OVER(PARTITION BY ID ORDER BY duration ASC)  as rnA  
         , ROW_NUMBER() OVER(PARTITION BY ID ORDER BY duration DESC) as rnD  
    from  #t
)

select cteMin.ID
     , cteMin.Duration as 'minDur',    cteMax.Duration as 'maxDur'
     , cteMin.Count    as 'minCount',  cteMax.Count    as 'maxCount' 
     , cteMin.A        as 'minA',      cteMax.A        as 'maxA'
from cte as cteMin 
join cte as cteMax 
  on cteMin.ID = cteMax.ID 
 and cteMin.rnA = 1 
 and cteMax.rnD = 1 
order by cteMin.ID;