SQL Query: Return Max value record of a Group

我的梦境 提交于 2019-12-17 14:57:04

问题


I have a sample table with similar structure & data as shown below:

+------+---------+-------------+------------+
| S_ID | S_NAME  | SUBJECT     | MARK_VALUE |
+------+---------+-------------+------------+
|    1 | Stud    | SUB_1       |         50 |
|    2 | Stud    | SUB_2       |         60 |
|    3 | Stud    | SUB_3       |         70 |
|    4 |  Stud_1 | SUB_1       |         40 |
|    5 |  Stud_1 | SUB_2       |         50 |
|    6 |  Stud_2 | SUB_2       |         40 |
+------+---------+-------------+------------+

Table has consolidated mark of each student in all subjects each that student has appeared.

Please help me, to write a query to extract MAXIMUM mark obtained by each student (irrespective of subject/other students), as below:

Group by S_Name & Max(MARK_Value)

+------+---------+-------------+------------+
| S_ID | S_NAME  | SUBJECT     | MAX_MARK   |
+------+---------+-------------+------------+
|    3 | Stud    | SUB_3       |         70 |
|    5 |  Stud_1 | SUB_2       |         50 |
|    6 |  Stud_2 | SUB_2       |         40 |
+------+---------+-------------+------------+

回答1:


use row_number() window function

select * from
 ( select *,
  row_number()over(partition by s_name order by MARK_VALUE desc) rn
 from table_name
) t where t.rn=1

or you can use corelated subquery

select t1.* from table_name t1
  where t.MARK_VALUE=(select max(MARK_VALUE) from table_name t2 where t2.S_NAME=t1.S_NAME)



回答2:


Analytic function ROW_NUMBER can be used to group rows by S_NAME (as you want to get maximum mark per student), and sort marks in descending order so that the max value raises to the top (i.e. gets row number = 1).

Then select rows with that row number value.

SQL> with test (s_id, s_name, subject, mark_value) as
  2    (select 1, 'stud', 'sub_1'  , 50 from dual union all
  3     select 2, 'stud', 'sub_2'  , 60 from dual union all
  4     select 3, 'stud', 'sub_3'  , 70 from dual union all
  5     select 4, 'stud_1', 'sub_1', 40 from dual union all
  6     select 5, 'stud_1', 'sub_2', 50 from dual union all
  7     select 6, 'stud_2', 'sub_2', 40 from dual
  8    )
  9  select s_id, s_name, subject, mark_value
 10  from (select s_id, s_name, subject, mark_value,
 11               row_Number() over (partition by s_name order by mark_value desc) rn
 12        from test
 13       )
 14  where rn = 1;

      S_ID S_NAME SUBJE MARK_VALUE
---------- ------ ----- ----------
         3 stud   sub_3         70
         5 stud_1 sub_2         50
         6 stud_2 sub_2         40

SQL>

if your database version doesn't support analytic functions, there's another option which isn't that good as it selects from the same table twice. You won't notice the difference if there aren't that many rows in a table, but performance will suffer on large data sets.

 <snip>
  9  select s_id, s_name, subject, mark_value
 10  from test
 11  where (s_name, mark_value) in (select s_name, max(mark_value) max_mark
 12                                 from test
 13                                 group by s_name);

      S_ID S_NAME SUBJE MARK_VALUE
---------- ------ ----- ----------
         3 stud   sub_3         70
         5 stud_1 sub_2         50
         6 stud_2 sub_2         40

SQL>



回答3:


Use row_number()

select * from
(
select *,row_number() over(partition by s_name order by MARK_VALUE desc) as rn
 from tablename
)A where rn=1



回答4:


Please try this.

Select B.* from @tbl AS B
INNER JOIN(
Select S_Name,MAX(MARK_VALUE) AS MARK_VALUE   from @tbl Group by S_Name) AS A
ON A.S_name=B.S_Name
AND A.MARK_VALUE = B.MARK_VALUE



回答5:


You can use group by and keep:

select max(s_id) keep (dense_rank first order by mark desc) as s_id,
       s_name,
       max(subject) keep (dense_rank first order by mark desc) as subject,
       max(max_mark)
from t
group by s_name;

keep is an Oracle extension that allows functionality like first_value() and last_value() for aggregation functions. In my experience, it is quite fast.



来源:https://stackoverflow.com/questions/55116179/sql-query-return-max-value-record-of-a-group

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!