向此结果集添加(SELECTING)另外两列

时间:2011-10-22 16:17:17

标签: mysql sql greatest-n-per-group

假设我有以下MySQL表:

user_id    date_of_application   date_ended    grade    status    
---------------------------------------------------------------

 1            2011-01-01         2011-02-28     1.0     Ended
 1            2011-02-02         2011-03-28     1.0     Ended
 1            2011-03-03         2011-04-28     (1.5)   Ended

 2            2011-01-01         2011-02-20     2.0     Ended
 2            2011-02-02         2011-03-11     2.5     Ended
 2            2011-03-03         2011-04-28     (1.0)   Ended

 1            2011-05-10              -          -      Pending
 2            2011-05-15              -          -      Pending

  • 请注意,只要所有以前的应用程序已结束(状态=已结束),该表就可以包含同一用户的多条记录
  • user_id 不是唯一的
  • 日期为 yy-mm-dd 格式
  • date_ended 成绩仅在应用程序结束时更新

我想在这里完成的是检索所有行(所有列一起) WHERE状态为'待定',并且成绩列的值为这些检索到的每一行都是最新成绩的值(在上面的括号中),其中该特定用户(或行)的状态为“已结束”。

结果:

user_id    date_of_application   date_ended    grade    status    
---------------------------------------------------------------

 1            2011-05-10         2011-06-10     1.5      Pending
 2            2011-05-15         2011-06-15     1.0      Pending


---- 修改 -----:

我不确定是否需要为这些添加创建另一个线程('如果我建议这样做的话也会这样做',无论如何 - 我决定使用ypercube的答案(见下文)(这有效,减去评论部分)。但是,除了上面生成的表之外,我还想再选择两列(每个列来自不同的表):

提供所需表格结果的工作代码(见上文):

SELECT user_id
     , date_of_application
     , date_ended
     , ( SELECT te.grade
         FROM TableX AS te
         WHERE te.status = 'Ended'
           AND te.user_id = t.user_id    

         ORDER BY te.date_ended DESC
         LIMIT 1
       ) AS grade
     , status
FROM TableX AS t
WHERE status = 'Pending'

现在我需要选择这两个其他列( is_first_time_user 名称)以及前面提到的结果表。请注意,这两个表的 user_id 都是唯一的:

表2:

user_id    is_firs_time_user
-----------------------------

 1               no
 2               no


表3:

user_id    name  
----------------------

 1        User A
 2        User B

3 个答案:

答案 0 :(得分:4)

这是一个包含派生内部表(ENDED)的解决方案,该内部表仅包含每个user_id的最新Ended记录。 (为清楚起见,我遗漏了与获得成绩问题无关的专栏。)

 SELECT PEND.user_id, ENDED.grade FROM YourTable PEND
    INNER JOIN 
       (
         SELECT user_id, grade FROM YourTable T1
         WHERE status = 'Ended' AND NOT EXISTS 
            (SELECT * FROM YourTable T2 
             WHERE T2.user_id = T1.user_id AND T2.date_ended > T1.date_ended) 
       ) ENDED
       ON PEND.user_id = ENDED.user_id
    WHERE PEND.status = 'Pending'

如果MySQL在嵌套SELECT方面遇到问题,或者“每个用户最近结束记录”的概念是您将在应用程序的其他位置使用的概念,或者您只是想要更清晰,那么您可以这样做:< / p>

 CREATE VIEW MostRecentEndedGrade (user_id, grade) AS
    SELECT user_id, grade FROM YourTable T1
         WHERE status = 'Ended' AND NOT EXISTS 
            (SELECT * FROM YourTable T2 
             WHERE T2.user_id = T1.user_id AND T2.date_ended > T1.date_ended) 

 SELECT PEND.user_id, ENDED.grade 
    FROM YourTable PEND INNER JOIN MostRecentEndedGrade ENDED
    ON PEND.user_id = ENDED.user_id
    WHERE PEND.status = 'Pending'

答案 1 :(得分:4)

SELECT user_d
     , date_of_application
     , date_ended
     , ( SELECT te.grade
         FROM TableX AS te
         WHERE te.status = 'Ended'
           AND te.user_id = t.user_id
           AND te.date_ended < t.date_of_application      --- not sure if 
                                                          --- this is needed
         ORDER BY te.date_ended DESC
         LIMIT 1
       ) AS grade
     , status
FROM TableX AS t
WHERE status = 'Pending'

答案 2 :(得分:0)

我认为最简单的方法是使用此查询构建视图:

SELECT user_id, MAX(date_ended) AS max_date FROM table 
WHERE status='ENDED' 
GROUP BY user_id

然后执行此查询以获取每个用户的最后一个成绩:

SELECT t1.user_id, t1.date_of_application,
   (SELECT t.date_ended, t.grade FROM table t, view v 
   WHERE t.user_id=v.user_id 
   AND t.date_ended = v.max_date),
   t1.status FROM table t1
WHERE status='PENDING'