2012-01-19 2 views
1

Я новичок в SQL Server, у меня есть вопрос. У меня есть таблица, как показано ниже:Как использовать подзапрос для запроса оценки студента?

NAME GRADE SUBJECT 
JOHN A  MATH 
JOHN C  PHYSIC 
JENNY B  PHYSIC 
JENNY C  MATH 
KENNY A  MATH 
KENNY B  PHYSIC 

.....

Я хочу запросить, чтобы

NAME MATH PHYSIC 
JOHN A  C 
JENNY C  B 
KENNY A  B 

Любой один помочь мне, пожалуйста! Благодаря

+0

Я считаю, что реляционная оператор PIVOT будет работать в этом случае, хотя у меня нет большого опыта, реализующий сам. http://msdn.microsoft.com/en-us/library/ms177410.aspx – hqrsie

ответ

2

Вы можете попробовать:

SELECT t.name, q1.grade AS Math, q2.grade AS Physic 
    (SELECT grade FROM your_table t1 
    WHERE t.name = t1.name 
    AND t1.subject = "MATH") q1, 
    (SELECT grade FROM your_table t2 
    WHERE t.name = t2.name 
    AND t2.subject = "PHYSIC") q2 
FROM your_table t 
GROUP BY name 
+1

Подзапросы могут быть менее эффективными, чем просто подключение к таблице в два раза. – JNK

5

В случае не все имена имеют оценки по всем предметам

SELECT 
    b.name, m.grade AS MATH, p.grade AS PHYSIC 
FROM 
    (
    SELECT DISTINCT name FROM MyTable 
    ) b 
    LEFT JOIN 
    MyTable m ON b.name = m.name AND m.subject = "MATH" 
    LEFT JOIN 
    MyTable p ON b.name = p.name AND p.subject = "PHYSIC" 
+0

Спасибо всем, но если у меня есть больше предметов, таких как школьный табло, и у меня есть предметная таблица, чтобы забить таблицу subject_id, как я могу запросить? – aliasosx

+1

@aliasosx ;: это будет новый вопрос. И с дополнительной информацией – gbn

0

Вы можете получить все записи для одного предмета и присоединиться к одной и той же таблицы для по другим вопросам:

select 
    m.NAME, 
    m.GRADE as MATH, 
    p.GRADE as PHYSIC 
from 
    thetable m 
    inner join thetable p on p.NAME = m.NAME and p.SUBJECT = 'PHYSIC' 
where 
    m.SUBJECT = 'MATH' 
+2

Конечно, мы надеемся, что все имена имеют оценки по обоим предметам ... – gbn

+0

И если они этого не сделают, вы можете изменить «внутреннее соединение» на «левое внешнее соединение» или использовать сводную таблицу в соответствии с моим или тполяк. –

4

Вы можете использовать PIVOT (начиная с SQL-сервера 2005):

SELECT * 
FROM (SELECT Name, Subject, Grade FROM Grades) o 
PIVOT(MAX(Grade) FOR Subject IN ([Math], [Physic])) p 

оператор Внутри PIVOT() вы должны определить агрегатную функцию, если каждый человек может иметь один класс для субъекта, то MAX() или MIN() является совершенным.

+0

Спасибо tpolyak, как мы можем изменить агрегированную функцию в PIVOT(), чтобы указать значение класса String? – aliasosx

+1

@aliasosx MAX() и MIN() функции поддерживают строки, тоже – tpolyak

0

Пример использования PIVOT:

DECLARE @Students TABLE 
(
    name varchar(10), 
    grade char(1), 
    [subject] varchar(10) 
); 

INSERT INTO @Students VALUES ('JOHN', 'A', 'MATH'); 
INSERT INTO @Students VALUES ('JOHN', 'C', 'PHYSIC'); 
INSERT INTO @Students VALUES ('JENNY', 'B', 'PHYSIC'); 
INSERT INTO @Students VALUES ('JENNY', 'C', 'MATH'); 
INSERT INTO @Students VALUES ('KENNY', 'A', 'MATH'); 
INSERT INTO @Students VALUES ('KENNY', 'B', 'PHYSIC'); 

SELECT * 
FROM @Students AS Students 
PIVOT 
( 
    MAX(Grade) 
    FOR [subject] IN ([MATH], [PHYSIC]) 
) AS StudentGrades 
+0

Спасибо Ɖiamond ǤeezeƦ. Я могу изменить «IN ([Maths], [Physics]) с подзапросом? например «IN (выберите тему из subject_table)» – aliasosx

+0

Нет. Вам нужно будет построить запрос динамически, как в этой статье: [Свертывает динамические столбцы в SQL Server 2005] (http://www.simple-talk.com/ сообщества/блоги/Андраш/Архив/2007/09/14/37265.aspx) –

Смежные вопросы