2009-12-27 108 views
0

以下是父/子關係中的兩個表。 什麼,我需要做的是有平均成績來選擇學生:如何在這種情況下重寫選擇查詢

CREATE TABLE dbo.Students(
Id int NOT NULL, 
Name varchar(15) NOT NULL, 
CONSTRAINT PK_Students PRIMARY KEY CLUSTERED 
(

CREATE TABLE [dbo].[Results](
Id int NOT NULL, 
Subject varchar(15) NOT NULL, 
Mark int NOT NULL 
) 

ALTER TABLE [dbo].[Results] WITH CHECK ADD CONSTRAINT [FK_Results_Students] FOREIGN KEY([Id]) 
REFERENCES [dbo].[Students] ([Id]) 

我寫這樣的查詢:

SELECT name , coalesce(avg(r.[mark]),0) as Avmark 
FROM students s 
LEFT JOIN results r ON s.[id]=r.[id] 
GROUP BY s.[name] 
ORDER BY ISNULL(AVG(r.[mark]),0) DESC; 

但結果是,所有學生desc中有平均大關order.What我需要是限制結果集與學生的平均分最高agaist其他,如果是兩個學生平均分50和1與25我只需要顯示那些學生與50.如果只有一個學生的平均分數最高 - 只有他必須出現在結果集中。我怎樣才能以最好的方式做到這一點?

+0

什麼版本的SQL Server? – 2009-12-27 19:53:11

回答

-1
SELECT name as 'ФИО', 
coalesce(avg(r.[mark]),0) as 'Средний бал' 
FROM students s 
LEFT JOIN results r 
ON s.[id]=r.[id] 
GROUP BY s.[name] 
HAVING AVG(r.[mark]) >= 50 
ORDER BY ISNULL(AVG(r.[mark]),0) DESC 

about HAVING clause

+0

-1這不回答問題。用戶沒有要求一個標記高於50的學生列表。用戶需要標記最高的用戶 - 不管標記是什麼。 – 2009-12-27 19:45:50

0

如果您使用MS SQL服務器的一個相對較新的版本,你可以使用WITH,使這個簡單的寫:

WITH T AS (
    SELECT 
     name, 
     coalesce(avg(r.[mark]),0) as mark 
    FROM students s 
    LEFT JOIN results r ON s.[id]=r.[id] 
    GROUP BY s.[name]) 
SELECT name as 'ФИО', mark as 'Средний бал' 
FROM T 
WHERE T.mark = (SELECT MAX(mark) from T) 
1

的SQL Server 2005+,使用CTE:

WITH grade_average AS (
    SELECT r.id, 
      AVG(r.mark) 'avg_mark' 
    FROM RESULTS r 
GROUP BY r.id), 
    highest_average AS (
    SELECT MAX(ga.avg_mark) 'highest_avg_mark' 
    FROM grade_average ga) 
SELECT DISTINCT 
     s.name, 
     ga.avg_mark 
    FROM STUDENTS s 
    JOIN grade_average ga ON ha.id = s.id 
    JOIN highest_average ha ON ha.highest_avg_mark = ga.avg_mark 

非CTE等價物:

SELECT DISTINCT 
     s.name, 
     ga.avg_mark 
    FROM STUDENTS s 
    JOIN (SELECT r.id, 
       AVG(r.mark) 'avg_mark' 
      FROM RESULTS r 
     GROUP BY r.id) ga ON ha.id = s.id 
    JOIN SELECT MAX(ga.avg_mark) 'highest_avg_mark' 
     FROM (SELECT r.id, 
         AVG(r.mark) 'avg_mark' 
       FROM RESULTS r 
      GROUP BY r.id) ga) ha ON ha.highest_avg_mark = ga.avg_mark 
0

這是否簡單?對於所有版本的SQL Server 2000+

SELECT TOP 1 WITH TIES 
    name, ISNULL(avg(r.[mark]),0) as AvMark 
FROM 
    students s 
    LEFT JOIN 
    results r ON s.[id]=r.[id] 
GROUP BY 
    s.[name] 
ORDER BY 
    ISNULL(avg(r.[mark]),0) DESC; 
相關問題