Join - Where语句中的子查询

时间:2015-12-07 13:51:06

标签: mysql sql

我已经暂时停留在这个问题上了一段时间。问题如下:

我有3张桌子。学生表,付款表和pivot course_student表。 学生可以参加许多课程,每个学生可以为他们学习的每门课程支付很多费用。此数据存储在我的付款表中,并引用了course_student_id。

我只需要学生最后一笔付款,其中包含有关学生付款的最新信息。

这是我的疑问:

SELECT * 
FROM payments p
JOIN course_student cs ON cs.id = p.course_student_id
JOIN students s ON s.id = cs.student_id
GROUP BY p.course_student_id
HAVING max(p.id) IN ( SELECT id FROM payments )

问题在于,当我实际上期待最后一行时,我只从支付表中找回每个course_student的第一条记录。

这是我想要回复的一个例子:

Students
student_name student_id course_student_id
XYZ                   1                 1

在付款表上,说我有3个条目为course_student_id = 1

Payments
 id course_student_id amount_paid
 1                  1         100
 2                  1         250
 3                  1         500

我需要查询才能返回上次付款的所有详细信息。

3 个答案:

答案 0 :(得分:3)

您可以使用派生表来获取学生付款的最长日期。如果最大日期应该是当然的,请将其包含在group by

SELECT s.id, t.course_id, t.mxdate --other columns as needed
FROM course_student cs
JOIN students s ON s.id = cs.student_id
JOIN (select course_student_id, course_id, max(payment_date) as mxdate from payments
                                 ---^ --        ^ --change these columns to be appropriate
      group by course_student_id, course_id) t
on t.course_student_id = s.id

答案 1 :(得分:1)

考虑尝试此解决方案。子选择为每个course_student_id创建所有学生付款的新列表,并选出最大的ID。

bytes_received = recvfrom(sd, readBuffer, NTP_PACKET_MAX, 0, (struct sockaddr *)&client, &len);
if (bytes_received == SOCKET_ERROR)
{
    int err = WSAGetLastError(); 
    // In debugger you must be here before err is set
    closesocket(sd);
    WSACleanup();
    std::string what{"Could not receive datagram."};
    what+= std::to_string(err);
    throw std::runtime_error(what.c_str());
}

答案 2 :(得分:0)

如何简化并使用limitorder by获取最新的付款信息?

SELECT * 
FROM payments p
JOIN course_student cs ON cs.id = p.course_student_id
JOIN students s ON s.id = cs.student_id
ORDER BY p.id desc
LIMIT 1;