1

我不久前读到了@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如果可能的话如何将过滤添加到第二个查询。

4

2 回答 2

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 中。

于 2012-08-23T15:08:00.840 回答
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。

于 2012-08-25T17:29:44.260 回答