不同组的最大值

时间:2012-07-17 09:39:58

标签: sql sql-server-2008

Column1 Column2 Column3
------- ------- -------
jim       1788    5F 
jim       2000    9F
jim       500     9F
ben       190     4H
matt      400     46
matt      20      3G

我需要运行一个输出:

的查询
Column1 MaxValue PL
------- ------- -------
jim       2000    9F
jim       2000    NULL
ben       190     4H
matt      400     46
matt      400     NULL

对于Column1中的每个值(例如jim,ben,matt):我们按Column1对数据进行分组,对于每个组,我们显示column2上具有最大值的行。 然后,对于以这种方式找到的每一行,它再次显示它但在column3中为NULL,如果Column1的批处理返回多于1行,并且Column2中的值小于上一步骤中找到的最大值。 ben 190 NULL不显示,因为我们在Column1上只有一次。

提前感谢您提供任何提示或建议。

这是我到目前为止所尝试的但是我收到一个错误,提示我在GROUP By子句中包含Column2和Column3,但是如果我这样做,则无法达到所需的输出,如上所示。

CREATE VIEW VIEWB AS 
   SELECT DISTINCT t1.Column1, 
          /* MAX_Value */
            (MAX(t1.[Column2])) AS [MAX Value], 
          /* PL */
            (CASE 
            WHEN t1.[Column2] = MAX(t1.[Column2]) THEN t1.[Column3]
            ELSE NULL
            END) AS PL
      FROM TABLEA AS t1
      GROUP BY t1.Column1;

5 个答案:

答案 0 :(得分:2)

试试这段代码:

DECLARE @t TABLE (Column1 VARCHAR(50), Column2 INT, Column3 VARCHAR(50))
INSERT  @t
VALUES  
('jim'       ,1788    ,'5F'),
('jim'       ,2000    ,'9F'),
('jim'       ,500     ,'9F'),
('ben'       ,190     ,'4H'),
('matt'      ,400     ,'46'),
('matt'      ,20      ,'3G')

;WITH a AS (
SELECT  *,
        ROW_NUMBER() OVER (PARTITION BY Column1 ORDER BY Column2 DESC) RowNum,
        MAX(Column2) OVER (PARTITION BY Column1) Maximum
FROM    @t
)

SELECT  Column1,
        Maximum,
        CASE WHEN RowNum = 1 THEN Column3 END
FROM    a
WHERE   RowNum IN (1, 2)
ORDER   BY Column3 DESC

如果需要,可以将其放在视图中。

答案 1 :(得分:1)

试试这个

;with cte as (select *,ROW_NUMBER() over(partition by Column1 
order by Column2 desc) as row_num from table_A),
a as (
select Column1,MAX(Column2) [Column2],null [row_num]
from table_A
group by Column1
having COUNT(*)>1),
b as (select Column1,Column2,Column3 from cte where row_num=1
union all
select * from a)
select  Column1,Column2 [MaxValue],Column3 [PL] from b
order by Column2 desc,Column1,ISNULL(Column3,'') desc

答案 2 :(得分:1)

with data as (
  select * from
  (values
    ( 'jim'   ,    1788  ,  '5F' ),
    ( 'jim'   ,    2000  ,  '9F' ),
    ( 'jim'   ,    500   ,  '9F' ),
    ( 'ben'   ,    190   ,  '4H' ),
    ( 'matt'  ,    400   ,  '46' ),
    ( 'matt'  ,    20    ,  '3G' )
  ) foo (col1, col2, col3)
),
maxes as (
  select d.col1, d.col2, d.col3
  from
    data d
    inner join (select col1, max(col2) as col2 from data group by col1) m on d.col1 = m.col1 and d.col2 = m.col2 
)
select col1, col2, col3
from maxes
union all
select col1, col2, null
from maxes
where exists (select 0 from data where data.col1 = maxes.col1 and data.col2 < maxes.col2)
order by col1, col3 desc

答案 3 :(得分:1)

declare @t table(column1 varchar(10),column2 int, column3 varchar(10))
insert into @t 
select 'jim',       1788,    '5F' union all  
select 'jim',       2000,    '9F' union all 
select 'jim',       500,     '9F' union all
select 'ben',       190,     '4H' union all
select 'matt',      400,     '46' union all
select 'matt',      20,      '3G'


select column1,column2,column3 from
(
select *, row_number() over (partition by column1 order by column2 desc) as sno from @t
) as t
where sno=1
union 
select t1.column1,t2.column2,NULL 
from @t  as t1 inner join
(
select Column1, max(Column2) as column2,count(*) as counting from @t 
group by column1 having count(*)>1
) as t2
on t1.column1=t2.column1 

答案 4 :(得分:1)

可能不是最有效的方法,所以如果你有一个非常大的表,这可能不是一个理想的解决方案,而是一个选项:

create table #temp (column1 varchar(10), column2 float, column3 varchar(10))

insert #temp select 'jim', 1788, '5F'
insert #temp select 'jim', 2000, '9F'
insert #temp select 'jim', 500, '9F'
insert #temp select 'ben', 190, '4H'
insert #temp select 'matt', 400, '46'
insert #temp select 'matt', 20, '3G'

SELECT column1, column2 as MaxValue, column3 as PL FROM #temp 
WHERE column2=(SELECT Max(column2) FROM #temp t2 WHERE t2.column1=#temp.column1)
union
SELECT column1, column2, NULL FROM #temp
WHERE column2=(SELECT Max(column2) FROM #temp t3 WHERE t3.column1=#temp.column1)
AND EXISTS(SELECT 1 FROM #temp t4 WHERE t4.column2<>#temp.column2 and t4.column1=#temp.column1)

DROP TABLE #temp