2012-10-01 65 views
4

我真的不知道如何把这个,但请检查下面的细节。作为列的SQL查询字段

学生

|Student_ID|Student_Name| 
|1   |Ryan  | 
|2   |Camille  | 
|3   |George  | 

|Student_ID|Subject |Grade 
|1   |Math |5 
|1   |English |3 
|1   |History |1 
|2   |Math |3 
|2   |English |4 
|2   |History |1 
|3   |Math |5 
|3   |English |1 
|3   |History |2 

是否有可能得到这样的结果?

Student_Name|Math|English|History 
Ryan  |5 |3  |1 
Camille  |3 |4  |1 
George  |5 |1  |2 

现在我已经通过与第一列名填充未绑定的DataGrid这样的在Hardway,那么学生的名字,然后添加细节为每个学生的名字。这很耗时,我想更好地优化查询。

在此先感谢。

回答

3

虽然@如果你有一个已知的一些科目约翰的回答会的工作,如果你有数目不详的主题,那么你可以使用准备好的语句生成此动态。这里是一个很好的文章:

Dynamic pivot tables (transform rows to columns)

您的代码应该是这样的:

SET @sql = NULL; 
SELECT 
    GROUP_CONCAT(DISTINCT 
    CONCAT(
     'MAX(case when Subject = ''', 
     Subject, 
     ''' then Grade end) AS ', 
     Subject 
    ) 
) INTO @sql 
FROM grade; 

SET @sql = CONCAT('SELECT s.Student_name, ', @sql, ' 
        FROM student s 
        LEFT JOIN grade AS g 
        ON s.student_id = g.student_id 
        GROUP BY s.Student_name'); 

PREPARE stmt FROM @sql; 
EXECUTE stmt; 
DEALLOCATE PREPARE stmt; 

SQL Fiddle With Demo

+0

我真的很喜欢这个!感谢您指出:) –

+0

我已经设法与@ John的答案合作,通过.net获取列名计数,然后用另一个数据集填充它。然后我继续用行填充另一个数据集。但你的答案很棒。哇,只是哇。谢谢。 –

+0

@bluefeet,我设法使用你的答案并将其转换为存储过程。非常感谢你。 –

11

尝试,

SELECT a.Student_name, 
     MAX(CASE WHEN subject = 'MATH' THEN grade ELSE NULL END) MathGrade, 
     MAX(CASE WHEN subject = 'ENGLISH' THEN grade ELSE NULL END) EnglishGrade, 
     MAX(CASE WHEN subject = 'History' THEN grade ELSE NULL END) HistoryGrade 
FROM Student a 
     LEFT JOIN Grade b 
      ON a.Student_ID = b.Student_ID 
GROUP BY a.Student_name 

SQLFiddle Demo

+1

谢谢,我会纳入这我在做什么,并会回来给你的结果。 –

+0

我注意到您在查询中预定义了主题名称,系统可以添加比上面给出的主题更多的主题。有没有办法没有预定义的查询?对不起我的英语不好。 –

+0

好的,这解决了我的问题,我只需要玩一下。谢谢。 –