如何使用group by子句加入

时间:2016-10-26 07:44:03

标签: sql-server sql-server-2008 join group-by

我有两个表,table1有两列

id     name
1      Amal
2      Varun
3      Sari

table2有3列

id      Subject     marks
1       Maths       80
1       Malayalam   75
1       History     45
2       Maths       90
2       Malayalam   85
2       History     50
3       Maths       88
3       Malayalam   75
3       History     80

我的问题是找到每个主题具有最大分数的名称(主题知识顶部),结果表必须包括字段名称主题和标记

我使用以下查询进行了测试

SELECT 
    table1.Student_Name, (table2.subject), max(table2.Marks_obt) 
FROM 
    table2
INNER JOIN
    table1 ON table2.stud_id = table1.Student_ID
GROUP BY 
   [Student_Name], table2.Subject 
HAVING
   MAX(Marks_obt) IN (SELECT MAX(Marks_obt) AS total_marks
                      FROM table2
                      GROUP BY subject)

在SQL Server 2008中,但我得到了结果

name    subject   
Sari    History     80
Varun   Malayalam   85
Amal    Maths       80
Varun   Maths       90

我如何以这种方式获得三个主题的顶部?

5 个答案:

答案 0 :(得分:1)

您可以使用ROW_NUMBER()

SELECT s.subject,s.name,s.marks
FROM(
    SELECT t1.*,t2.subject,t2.marks,
           ROW_NUMBER() OVER(PARTITION BY t2.subject ORDER BY t2.marks DESC) as rnk
    FROM Table1
    JOIN Table2
     ON table2.stud_id = table1.Student_ID) s
WHERE s.rnk = 1

答案 1 :(得分:0)

使用Rank您不会错过任何人,例如两个人在同一主题中获得相同的最高分。如果你想查询找到第二高分或第三高使用Dense_Rank()函数,甚至dense_rank()也可用于找到第一高。更多cilck here

SELECT NAME,
       SUBJECT,
       MARKS
FROM   (SELECT NAME,
               SUBJECT,
               MARKS,
               rank()
                 OVER(
                   PARTITION BY [SUBJECT]
                   ORDER BY MARKS DESC) RNO
        FROM   #TABLE1 T
               JOIN #TABLE2 T2
                 ON T.ID = T2.ID) A
WHERE  RNO = 1 

答案 2 :(得分:0)

CREATE TABLE #table1 
(Student_ID INT,
Student_Name VARCHAR(20))

INSERT INTO #table1
SELECT 1,'Amal'
UNION 
SELECT  2,'Varun'
UNION
SELECT 3,'Sari'


CREATE TABLE #table2
(
stud_id INT,
[subject] VARCHAR(20),
Marks_obt INT
)

INSERT INTO #table2
SELECT 1,'Maths',80
UNION
SELECT 1,'Malayalam',75
UNION
SELECT 1,'History',45
UNION
SELECT 2,'Maths',90
UNION
SELECT 2,'Malayalam',85
UNION
SELECT 2,'History',80
UNION
SELECT 3,'Maths',88
UNION
SELECT 3,'Malayalam',75
UNION
SELECT 3,'History',80   

/*Table 1*/
SELECT * FROM  #table1
/*Table 2*/
SELECT * FROM #table2


/*Top Mark*/
SELECT [subject],
   Student_Name,
   Marks_obt
FROM(SELECT Student_Name,
           [subject],
           Marks_obt,
           RANK()
             OVER(
               PARTITION BY [subject]
               ORDER BY Marks_obt DESC) RowNum
    FROM   #table1 T1
           JOIN #table2 T2
             ON T1.Student_ID= T2.stud_id) AS data
WHERE  data.RowNum = 1 


DROP TABLE #table1,#table2

答案 3 :(得分:0)

你可以像这样使用交叉申请

   with maxi as (
   select Subject, max(marks) maximark from table2
   group by Subject
   )
   select * from maxi f1
   cross apply
   (
   select top 1 f2.name from table1 f2 inner join table2 f3 on f2.id=f3.id
   where f1.maximark=f3.marks and f1.subject=f3.subject   
   ) f3

如果有多个用户可以使用最大标记,请删除“top 1”

答案 4 :(得分:0)

其他解决方案:

   with maxi as (
   select Subject, max(marks) maximark from table2
   group by Subject
   )
   select (select top 1 f2.name from table1 f2 inner join table2 f3 on f2.id=f3.id where f1.maximark=f3.marks and f1.Subject=f3.Subject) as Name, f1.* 
   from maxi f1