SQL结果集的排序、分组和筛选

SQL结果集的排序、分组和筛选,sql,mysql,Sql,Mysql,我在数据库中有许多“容器”,每个容器包含零个或多个项目。每个项目都有一个名称、分数、表示它已添加到容器的时间戳,以及容器ID上的一个外键 我想获取顶部项目得分为5或更高的所有容器(这意味着不返回空容器)。由于容器在本例中的作用类似于堆栈,因此具有最高“添加时间”的项被视为“顶部”项 目前,我正在使用以下SQL: SELECT * FROM ( SELECT name, container_id, score FROM items ORDER BY added_time DESC )

我在数据库中有许多“容器”,每个容器包含零个或多个项目。每个项目都有一个名称、分数、表示它已添加到容器的时间戳,以及容器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

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

也许这就是你想要的:

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

尝试以下任何一种方法。它依赖于(容器id、添加的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);

结果表明,内部select有一个左连接,这导致了减速删除,从而将查询时间减少到了0.01秒。这意味着丢失由联接带来的信息,但这些信息可以在以后填充(返回的最终行数“很小”,因此我是否必须为每个行运行查询以复制左联接的效果无关紧要)。

我不确定为什么要使用MAX(score)-我想找到顶部项具有给定分数的容器。换句话说,我需要找到每个容器的顶部项目,然后过滤掉不符合条件的项目。但为了更快,您可以删除第一个不符合mach标准(分数小于5)的项目,然后在容器中搜索顶部分数。。正如您所描述的问题:“我想要获取顶部项目得分为5或更高的所有容器”我不想要容器中的顶部(即max())得分,我想要顶部(即最后添加的)项目的得分。