对SQL结果集进行排序,分组和过滤

时间:2010-12-10 15:41:44

标签: sql mysql

我在数据库中有许多“容器”,每个容器包含零个或多个项目。每个项目都有一个名称,分数,表示它的时间戳已添加到容器中,以及容器ID上的外键。

我想获取顶级项目得分为5或更高的所有容器(这意味着不返回空容器)。由于容器在这种情况下就像堆栈一样,具有最高“添加时间”的项目被视为“顶部”项目。

目前,我正在使用以下SQL:

SELECT * FROM (
  SELECT name, container_id, score
  FROM items
  ORDER BY added_time DESC
) AS temptbl
GROUP BY container_id
HAVING score >= 5

这似乎给了我想要的结果,但是当项目数量开始增加时速度非常慢 - 在8000个容器上运行查询而在MySQL控制台上运行10000个项目需要将近6秒,这太慢了。我做的事情显然效率低下吗?

3 个答案:

答案 0 :(得分:0)

也许这就是你想要的:

SELECT name, container_id, score
FROM items AS tb1
RIGHT JOIN (SELECT container_id, Max(added_time) as added_time 
    FROM items GROUP BY tablename) as tb2 on 
    tb1.container_id = tb2.container_id AND tb1.added_time = tb2.added_time
WHERE score >= 5

答案 1 :(得分:0)

请尝试以下任一操作。它依赖于(container_id,added_id)是唯一的。

select *
  from (select container_id, max(added_time) as added_time
          from items
         group by container_id
       ) as topitems 
  join items on(topitems.container_id = items.container_id and 
                topitems.added_time   = items.added_time)
 where items.score >= 5;


select *
  from items a
 where score >= 5
   and (added_time) = (select max(b.added_time)
                         from items b
                        where a.container_id = b.container_id);

答案 2 :(得分:0)

事实证明内部选择有一个LEFT JOIN导致减速 - 删除将查询时间减少到0.01秒。这意味着丢失连接带来的信息,但之后可以填写(返回的最终行数是'小',因此如果我必须为每个行运行查询以复制左边的效果,这无关紧要JOIN)。