对于使用groupwise最大值的查询真的很困难,任何帮助都会非常感激。如果我不应该使用groupwise最大值,请随时指出。
我有两个表application
和email
,一个应用程序可以有很多电子邮件。我在我的查询中尝试做的是从应用程序获取所有详细信息并加入电子邮件表(我实际上只从电子邮件中获取另一个表的外键,表明该电子邮件是否已被回复) ,根据最大值(时间戳)发送最后一封电子邮件,这就是我尝试使用groupwise最大值的原因。
我已经尝试过了,但它似乎重复了每一行:
SELECT `application` . * , `email1`.`student_email_id` AS `email_student_email_id`
FROM `application`
LEFT JOIN (
SELECT MAX( tstamp ) AS tstamp, id, student_email_id, application_id
FROM email
GROUP BY id, student_email_id, application_id
) AS email1 ON `email1`.`application_id` = `application`.`id`
WHERE `application`.`status` = 'returned'
这一开始似乎起作用,但现在引起了问题,我确信它的代码非常草率:
select `application`.*, `email1`.`student_email_id` as `email_student_email_id`
from `application`
left join (
select student_email_id, max(tstamp) as tstamp, application_id
from email
group by application_id, tstamp
order by tstamp desc
limit 1) as email1 on `email1`.`application_id` = `application`.`id`
where `application`.`status` = 'returned'
如果您需要查看更多代码,请高度赞赏任何指导!感谢。
如果我的数据库设置需要进一步清晰,应该发生什么(遗漏了不重要的部分):
Application Table
+----+----------+
| id | status |
+----+----------+
| 1 | returned |
+----+----------+
Email Table
+----+------------+----------------+------------------+
| id | tstamp | application_id | student_email_id |
+----+------------+----------------+------------------+
| 1 | 2014-12-26 | 1 | NULL |
| 2 | 2014-12-27 | 1 | 3 |
+----+------------+----------------+------------------+
查询应显示以下内容:
+----+----------+------------------------+
| id | status | email_student_email_id |
+----+----------+------------------------+
| 1 | returned | 3 |
+----+----------+------------------------+
上面的第一个解决方案显示了所有内容的重复(可能是我几乎在那里),第二个解决方案显示了连接表列的null,尽管我确信它在一个阶段或至少在隔离中工作!
答案 0 :(得分:4)
您正在Email
表格中查找每个不同application_id
的最新行。
你得到的子查询并不是很正确。这就是你如何做到的。
SELECT s.application_id, e.student_email_id
FROM email e
JOIN (
SELECT MAX(tstamp) tstamp, application_id
FROM email
GROUP BY application_id
) s ON e.application_id = s.application_id AND e.tstamp = s.tstamp
还有另一种方法可以做到这一点,这可能会更有效率。如果id
列是自动增量列,它将起作用。
SELECT s.application_id, e.student_email_id
FROM email e
JOIN (
SELECT MAX(id) id
FROM email
GROUP BY application_id
) s ON e.id = s.id
前面这些子查询中的任何一个都会为每个application_id获取最新的student_email_id。第二个使用JOIN仅为每个application_id提取最高的id号,并使用该id查找最新的student_email_id。
你的子查询是这样的。它没有得到你所希望的。
SELECT MAX( tstamp ) AS tstamp, id, student_email_id, application_id /*wrong*/
FROM email
GROUP BY id, student_email_id, application_id
您按ID分组。这意味着您将获得所有细节行。这不是你想要的。即便如此
SELECT MAX( tstamp ) AS tstamp, student_email_id, application_id /*wrong*/
FROM email
GROUP BY student_email_id, application_id
将为每个application_id值提供多条记录。
所以你需要的查询是:
SELECT application.* , email1.student_email_id AS email_student_email_id
FROM application
LEFT JOIN (
SELECT s.application_id, e.student_email_id
FROM email e
JOIN (
SELECT MAX(id) id
FROM email
GROUP BY application_id
) s ON e.id = s.id
) AS email1 ON email1.application_id = application.id
WHERE application.status = 'returned'
当您设计这样的查询时,从内到外进行测试是明智的,从最里面的子查询开始。