SQL显示来自Junction表的最新更新

时间:2013-05-07 02:17:41

标签: sql join

我一直在对这个小问题做一些研究,并决定是时候提问了。这可能是一个很长的帖子所以我为此道歉。

这是一个学校作业,我只是在玩一些SQL,我使用mySQL作为DBMS。

我正在尝试使用SQL语句中的JOIN显示所有成员的信息。

以下是我所拥有的表格的简要概述

成员

  • ID
  • Firs_Name
  • 姓氏
  • User_ID(用户的外键表)
  • Membership_Type( Membership_type 表的外键)
  • 电话
  • 电子邮件
  • 年龄

Grade_Type

  • ID
  • 描述

Grade_type表中的数据如下所示

ID  DESCRIPTION  

 1  A Grade      
 2  B Grade      
 3  C Grade      
 4  D Grade      
 5  E Grade      
 6  F Troop      

成绩(这是一个联结表,其中包含会员ID,成绩和日期,以保留成绩晋升和降级的历史记录。

  • ID
  • Member_ID(FK到成员
  • Grade_ID(FK到 grad_type
  • 日期

此表中的数据如下所示,如您所见,多个成员的成绩已经改变了2-3次

ID  MEMBER_ID  GRADE_ID  DATE        

 1          1         3  2013-02-12  
 2          2         2  2013-03-14  
 3          4         2  2013-01-16  
 4          3         6  2013-01-29  
 5          5         1  2012-10-18  
 6          4         4  2013-04-09  
 7          6         5  2012-12-11  
 8          1         2  2013-05-03  
 9          2         3  2013-04-10  
10          3         5  2013-03-13  
11          4         3  2013-03-06  
12          5         3  2012-12-13  
13          6         4  2013-04-09  
14          1         6  2013-05-06 

我想做的是有一个这样的输出,最后的等级,显示最近的变化,下面也是我用来接收这个的SQL状态,我正在努力弄清楚在哪里,或者如何放入'MAX(DATE)字段或类似的东西。

ID  FIRST_NAME  LAST_NAME  PHONE      EMAIL                    AGE  USERNAME    Membership Type       ANNUAL_FEE  Grade    
 1  John        Lennon     9345 3253  jlennon@gmail.com         38  jlennon     Full Standard Member         185  C Grade  
 2  Devin       Townsend   9342 3421  dtownsend@gmail.com       78  dtownsend   Senior 70+                   135  B Grade  
 3  Mikael      Akerfeldt  9342 5675  makerfeldt@gmail.com      41  makerfeldt  Full Standard Member         185  F Troop  
 4  Dexter      Morgan     8324 3211  dmorgan@gmail.com         67  dmorgan     Social                        35  B Grade  
 5  Martin      Mendez     7845 3454  mmendez@gmail.com         82  mmendez     Senior 70+                   135  A Grade  
 6  Paul        McCartney  7543 8765  pmccartney@gmail.com      36  pmcartney   Social                        35  E Grade

SQL语句

SELECT `members`.`ID`, `members`.`FIRST_NAME`, `members`.`LAST_NAME`,`members`.`PHONE`,`members`.`EMAIL`,`members`.`AGE`, 
`users`.`USERNAME`, `membership_type`.`DESCRIPTION` AS 'Membership Type',`membership_type`.`ANNUAL_FEE`, `grade_type`.`DESCRIPTION` AS 'Grade' FROM `2013evccor`.`members`
JOIN `users` ON `members`.`USER_ID` = `users`.`ID`
JOIN `membership_type` ON `members`.`MEMBERSHIP_TYPE` = `membership_type`.`ID`
LEFT JOIN (`grades` JOIN `grade_type` ON `grade_type`.`ID` = `grades`.`GRADE_ID`) ON `grades`.`MEMBER_ID` = `members`.`ID` GROUP BY `members`.`ID`

我试过的另一个声明就是这样,以及JOIN中的嵌套声明

SELECT `grades`.`MEMBER_ID`,`grades`.`GRADE_ID`,MAX(`grades`.`DATE`) AS 'DATE' FROM `grades` GROUP BY `grades`.`MEMBER_ID`

然而,这会返回此数据:

MEMBER_ID  GRADE_ID  DATE        
---------  --------  ------------
        1         3  2013-05-06  
        2         2  2013-04-10  
        3         6  2013-03-13  
        4         2  2013-04-09  
        5         1  2012-12-13  
        6         5  2013-04-09

现在上面的日期是每个成员的最新日期,但成绩不正确,例如,Member_ID:1现在在Grade_ID中:6从'2013-05-06'开始而不是Grade_ID:3

也许我应该尝试使用 grade 表作为select语句FROM子句中的起始点。如果我这样做,我是否仍然可以通过成员表中的外键轻松获取成员用户名和成员资格信息?

对不起,这是一个很长的帖子,我真的不知道怎么把所有这些都放进去了,我想彻底描述我已经尝试过的所有内容。

1 个答案:

答案 0 :(得分:0)

您可以从grades上的查询开始查找会员最新成绩的日期(假设会员在指定日期只有1个成绩)。然后将其加入grades表,以过滤掉每个成员的最大日期等级。然后使用此结果加入其他表(grade_typemember)。如果成员可能没有成绩并且您希望它们无论如何都显示在列表中(没有成绩),那么您将需要按成员和外部联接驱动查询到子查询结果。

SELECT g.member_id, t.description
  FROM grades g
  INNER JOIN ( SELECT member_id, max(dte) as dte
         FROM grades
         GROUP BY member_id
          ) m
    ON (g.member_id = m.member_id AND g.dte = m.dte)
  INNER JOIN grade_type t ON (g.grade_id = t.id)
  ORDER BY g.member_id