2010-12-10 2 views
0

У меня есть несколько «контейнеров» в базе данных, каждая из которых содержит ноль или несколько элементов. Каждый элемент имеет имя, оценку, временную метку, представляющую ее, которая была добавлена ​​в контейнер, и внешний ключ в идентификаторе контейнера.Порядок, группировка и фильтрация наборов результатов SQL

Я хочу получить все контейнеры, в которых верхний элемент имеет баллы 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 контейнеров и 10000 элементов занимает около 6 секунд на консоли MySQL, что слишком медленно. Я делаю что-то явно неэффективное?

ответ

0

Оказывается, что внутренний выбор был LEFT JOIN, который вызывает замедление - удаление, что позволило сократить время запроса на 0,01 с. Это означает потерю информации, вносимой в соединение, но которая может быть заполнена впоследствии (окончательное число возвращенных строк является «маленьким», поэтому не имеет значения, должен ли я запускать запрос для каждого, чтобы воспроизвести эффекты LEFT ПРИСОЕДИНИТЬСЯ).

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 
+0

Я не уверен, почему я буду использовать MAX (оценка) - Я хочу найти контейнеры, где верхний элемент имеет заданный балл. Другими словами, мне нужно найти верхний элемент для каждого контейнера, а затем отфильтровать те, которые не соответствуют критериям. – pwaring 2010-12-10 16:04:47

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); 
Смежные вопросы