2012-02-04 55 views
14

假设我有以下两个表:LEFT JOIN的最大价值

STUDENT 
studentid lastname firstname 
1   Smith  John 
2   Drew  Nancy 

STUDENT_STORY 
studentid dateline storyid status 
1   1328313600 10  2 
1   1328313601 9   1 
2   1328313602 14  2 
2   1328313603 12  1 

现在,我需要一个SQL查询,将与该学生的学生的故事台最新的故事沿着选择的每个学生。

我想这一点:

SELECT s.*, ss.* 
FROM student AS s 
LEFT JOIN (
    SELECT * 
    FROM student_story 
    WHERE student_story.studentid = s.studentid 
    ORDER BY dateline DESC LIMIT 1 
) AS ss ON (ss.studentid = s.studentid) 

然而,此查询不起作用。它抱怨s.studentid是子查询的where子句中的未知字段。

请建议我如何才能实现我想要做的。

谢谢。

回答

17

尝试这样:

SELECT 
    s.*, 
    ss.* 
FROM 
    student AS s 
LEFT JOIN 
    student_story AS ss 
ON (ss.studentid = s.studentid) 
WHERE ss.dateline = (
    SELECT 
    MAX(dateline) 
    FROM 
    student_story AS ss2 
    WHERE 
    ss2.studentid = s.studentid 
) 
+1

现在,当我仔细想想,这可能如果两次有相同的时间戳多个条目返回相同的学生,所以可能不要使用这个。 – Detheroc 2012-02-04 22:10:36

+0

除非出现严重错误,否则绝不应该这样。如何修复此查询,以便在多个条目具有相同时间戳的情况下不会返回同一个学生两次? – akanevsky 2012-02-04 23:01:08

+0

如果student_story表中的ID也保证随时间增加,您可以选择并比较最大ID。虽然在你的例子中似乎不是这种情况,所以问题可能非常棘手。 Vyktor的解决方案没有工作吗?这似乎很合理。 – Detheroc 2012-02-05 11:31:52

1

这个连接应该这样做:

SELECT s.*, ss.* 
FROM student_story AS ss 
LEFT JOIN student AS s 
    ON student_story.studentid = s.userid 
GROUP BY ss.studentid 

GROUP BY应采取最后一排,所以最后的故事=最后一排,如果它不会工作尝试:

GROUP BY ss.studentid, ss.dateline DESC 

我不确定,请和结果进行评论

+0

编号“服务器可以从这个非聚集列自由选择任何值”https://dev.mysql.com/doc/refman/5.7/en/group-by-modifiers.html – 2018-01-05 19:16:00

4
SELECT s.*, ss.* 
FROM student AS s 
LEFT JOIN (

SELECT * FROM student_story  
ORDER BY dateline DESC LIMIT 1 
) 
AS ss ON (ss.studentid = s.studentid) 
+0

我从所有提供的答案中学到了东西但你的工作让我做得更好。 – 2016-11-27 19:44:15

+0

这不起作用,因为子选择只会为所有不能加入的学生返回一个结果,但只有最新的student_story。 – Roben 2017-04-13 10:09:55

0

你需要添加一个自动的和独特的ID上student_story表的每一行。

然后你会区分它们。 (假设studentstory.new_id)

select s.*, ss.* 
from student s 
left join student_story ss on ss.studentid = s.userid 
where ss.new_id = (select ss.new_id from student s 
    group by dateline 
    order by dateline desc 
    limit 1 
) 
1
SELECT 
    s.sale_id, 
    s.created_at, 
    p.created_at, 
    DATEDIFF(p.created_at, s.created_at) AS days 
FROM 
    pos_sales s 
     LEFT JOIN 
    pos_payments p ON p.sale_id = s.sale_id 
     AND 
    p.created_at = (SELECT 
      MAX(p2.created_at) 
     FROM 
      pos_payments p2 
     WHERE 
      p2.sale_id = p.sale_id) 
0

另一种方法是使一个LEFT JOINNOT EXISTS()条件。根据情况,这可以提供更多的灵活性;然而,它也将显示重复的结果,如果有两个条目,每个学生相同dateline

SELECT s.*, ss.* 
FROM student AS s 
LEFT JOIN student_story AS ss ON ss.studentid = s.studentid AND NOT EXISTS 
    (SELECT * FROM student_story AS ss2 
    WHERE ss2.studentid = ss.studentid AND ss2.dateline > ss.dateline)