检索每个组中的最后一个筛选记录

时间:2012-08-23 13:44:40

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

我读了一下@Bill Karwin的优秀答案:

https://stackoverflow.com/a/1313293/317889

这几乎回答了这个问题,但我最近不得不更新我的查询以过滤联接表状态。

我在下面写了两个查询,类似于上面帖子中的查询。第一个慢速查询使用连接表状态过滤:

SELECT m.*, t1.* FROM mood m 
LEFT JOIN temper t ON ( m._id = t.mood_id ) 
WHERE grantee_username = "username" 
AND m.status_id != 1 // NOT INTERESTED IN THIS FILTER
AND t.status_id != 1 // FILTERING 
GROUP BY m._id;

使用第二个查询我不知道如何添加过滤以使其按上述方式工作:

SELECT m.*, t1.* FROM mood m 
LEFT JOIN temper t1 ON ( m._id = t1.mood_id ) 
LEFT JOIN temper t2 ON ( t1.mood_id = t2.mood_id AND t1._id < t2._id ) 
WHERE t2._id IS NULL 
AND m.grantee_username = "username" 
AND m.status_id != 1; // NOT INTERESTED IN THIS FILTER

第一个查询工作正常,但被认为比第二个查询慢。

第二个查询用于将所有心情记录与其相关的最后一个脾气记录相关联,但最后一个脾气记录可能具有我不想要的状态1。

任何见解都会引起人们的兴趣。我总是可以使用第一个查询,但出于性能考虑,我想弄清楚如果可能的话,如何将t.status_id过滤添加到第二个查询。

2 个答案:

答案 0 :(得分:1)

我认为您的第二个查询最后缺少GROUP BY。

此版本在子查询中添加了过滤器:

SELECT m.*, t1.*
FROM mood m  LEFT JOIN
     (select t.*
      from temper t
      where t.status_id != 1
     ) t1
     ON m._id = t1.mood_id  LEFT JOIN
     temper t2
     ON t1.mood_id = t2.mood_id AND t1._id < t2._id
WHERE t2._id IS NULL AND
      m.grantee_username = "username" 
GROUP BY m._id;

您是否也希望过滤器在t2上?

顺便说一句,您在MySQl中使用了一个名为Hidden Columns的功能 - 您在一列上聚合但在其他列上返回没有聚合函数的行。此功能仅适用于MySQL。

答案 1 :(得分:1)

好的,毕竟它并不是太难以理解:

SELECT m.*, t1.* FROM mood m 
LEFT JOIN temper t1 ON ( m._id = t1.mood_id AND t1.status_id !=1) 
LEFT JOIN temper t2 ON ( t1.mood_id = t2.mood_id AND t1._id < t2._id AND t2.status_id !=1 ) 
WHERE t2._id IS NULL 
AND m.grantee_username = "username" 
AND m.status_id != 1; // NOT INTERESTED IN THIS FILTER

需要将过滤器(status_id)添加到每个JOIN。

相关问题