SQL表/数据透视表

时间:2016-04-21 00:11:06

标签: sql oracle

我有一个select语句从数据库中获取名称和度数,类似于以下内容:

ID_Num  F_Name  L_Name  Deg_Type     Deg_Desc                        Grad_Date
001     Tyler   Lee     Degree       Associates of Computer Science  08-Aug-2012
002     Tyler   Lee     Degree       Bachelors of Computer Science   08-Aug-2014
003     Tyler   Lee     Certificate  Supervisory Certificate         08-Aug-2013
004     Susie   Q       Degree       Associates of Mathematics       08-Aug-2014

我需要一行中的所有数据,如下所示,我该怎么做?

ID_Num  F_Name  L_Name  Deg_Type  Deg_Desc                        Grad_Date    Deg_Type  Deg_Desc                       Grad_Date    Deg_Type     Deg_Desc                 Grad_Date
001     Tyler   Lee     Degree    Associates of Computer Science  08-Aug-2012  Degree    Bachelors of Computer Science  08-Aug-2014  Certificate  Supervisory Certificate  08-Aug-2013
002     Susie   Q       Degree    Associates of Mathematics       08-Aug-2014  (null)    (null)                         (null)       (null)       (null)                   (null)

2 个答案:

答案 0 :(得分:0)

您可以对同一个表进行连接,但是您会人为地将结果数量限制为您指定的多个连接数(例如,这不是您想要的):

SELECT * FROM tbl AS t1 LEFT JOIN tbl AS t2 LEFT JOIN... where t1.F_Name=t2.F_Name and t1.L_Name=t2.L_Name and .....

您真正想要做的是规范化您的数据,以便您拥有一个单独的“学生”或“人”表,以及一个带有外键的“学位”表:

Table "Student":
ID F_Name L_Name
1  Tyler  Lee
1  Susie  Q

Table "Degree":
Student_ID  Desc                            Grad_Date...
1           Associates of Computer Science  08-Aug-2012...
1           Associates of Mathematics       08-Aug-2014...

然后您的查询是对两个表的简单连接:

SELECT * FROM Student s LEFT JOIN Degree d on d.Student_ID=s.ID;

如果您想要一组固定的学位可供选择,您可以让'Degree'存储不同类型的学位与他们自己的学位ID,然后有一个学生ID到学位ID的映射表。 / p>

答案 1 :(得分:0)

这很难,因为你事先不知道(或者你?)度数最多的人有多少度。执行此操作的最佳方法是使用perl或某种脚本语言创建代码,这些代码可以(a)查询表以查找度数最多的人,然后(b)使用该许多其他列动态创建查询。

但如果我们假设某人的最高学位是4,那么这应该有效:

SELECT ID_Num  
     , F_Name  
     , L_Name  
     , max(case when r=1 then Deg_Type else null end) as Deg_Type_01
     , max(case when r=1 then Deg_Desc else null end) as Deg_Desc_01
     , max(case when r=1 then Grad_Date else null end) as Grad_Date_01
     , max(case when r=1 then Deg_Type else null end) as Deg_Type_02
     , max(case when r=1 then Deg_Desc else null end) as Deg_Desc_02
     , max(case when r=1 then Grad_Date else null end) as Grad_Date_02
     , max(case when r=1 then Deg_Type else null end) as Deg_Type_03
     , max(case when r=1 then Deg_Desc else null end) as Deg_Desc_03
     , max(case when r=1 then Grad_Date else null end) as Grad_Date_03
     , max(case when r=1 then Deg_Type else null end) as Deg_Type_04
     , max(case when r=1 then Deg_Desc else null end) as Deg_Desc_04
     , max(case when r=1 then Grad_Date else null end) as Grad_Date_04
  FROM (select ID_Num, F_Name, L_name
             , Deg_Type, Deg_Desc, Grad_Date
             , row_number() OVER (PARTITION BY ID_Num, F_Name, L_name) 
          from Student) as a
 GROUP BY ID_Num  
     , F_Name  
     , L_Name ;

我无法访问oracle系统,所以如果这不起作用,请告诉我。