2015-05-09 6 views
1

Я новый студент по ИТ, и у меня есть несколько школьных примеров.SQL, способ сделать утверждение короче?

Здесь у меня есть оператор SQL, который очень длинный и медленный для загрузки. Кто-нибудь знает, как сделать это меньше? Использование MySQL

SELECT genre, titel, speelduur 
FROM film 
    WHERE speelduur = 
    (SELECT MAX(speelduur) 
    FROM film 
    WHERE genre ='Actie') 
AND genre = 'Actie' 
OR speelduur = 
    (SELECT MAX(speelduur) 
    FROM film 
    WHERE genre ='Avontuur') 
AND genre = 'Avontuur' 
OR speelduur = 
    (SELECT MAX(speelduur) 
    FROM film 
    WHERE genre ='Comedie') 
AND genre = 'Comedie' 
OR speelduur = 
    (SELECT MAX(speelduur) 
    FROM film 
    WHERE genre ='Dans') 
AND genre = 'Dans' 
OR speelduur = 
    (SELECT MAX(speelduur) 
    FROM film 
    WHERE genre ='Drama') 
AND genre = 'Drama' 
OR speelduur = 
    (SELECT MAX(speelduur) 
    FROM film 
    WHERE genre ='Epos') 
AND genre = 'Epos' 
OR speelduur = 
    (SELECT MAX(speelduur) 
    FROM film 
    WHERE genre ='Fantasie') 
AND genre = 'Fantasie' 
OR speelduur = 
    (SELECT MAX(speelduur) 
    FROM film 
    WHERE genre ='Historisch') 
AND genre = 'Historisch' 
OR speelduur = 
    (SELECT MAX(speelduur) 
    FROM film 
    WHERE genre ='Horror') 
AND genre = 'Misdaad' 
OR speelduur = 
    (SELECT MAX(speelduur) 
    FROM film 
    WHERE genre ='Musical') 
AND genre = 'Musical' 
OR speelduur = 
    (SELECT MAX(speelduur) 
    FROM film 
    WHERE genre ='Mysterie') 
AND genre = 'Mysterie' 
OR speelduur = 
    (SELECT MAX(speelduur) 
    FROM film 
    WHERE genre ='Oorlog') 
AND genre = 'Oorlog' 
OR speelduur = 
    (SELECT MAX(speelduur) 
    FROM film 
    WHERE genre ='Rampen') 
AND genre = 'Rampen' 
OR speelduur = 
    (SELECT MAX(speelduur) 
    FROM film 
    WHERE genre ='Religieus') 
AND genre = 'Religieus' 
OR speelduur = 
    (SELECT MAX(speelduur) 
    FROM film 
    WHERE genre ='Romantiek') 
AND genre = 'Romantiek' 
OR speelduur = 
    (SELECT MAX(speelduur) 
    FROM film 
    WHERE genre ='Science Fiction') 
AND genre = 'Science Fiction' 

Вы видите мою проблему прямо: P

ответ

0
select f.genre, 
     f.title, 
     f.speeldur 
from film f 
    join (
     select  genre, 
        max(speelduur) as max_speelduur_for_genre 
     from  film 
     group by genre 
     ) v 
    on f.genre = v.genre 
    and f.speeldur = v.max_speelduur_for_genre 
+0

Да, спасибо, это отлично работает !!! –

+0

Исходный запрос возвратил 'MAX (speelduur)' для жанра ''Horror'', а затем сопоставил его с строками с жанром' 'Misdaad''. – spencer7593

+0

@ spencer7593 Я подозреваю, что это была опечатка, если OP указывает, что она работает. Я не уверен, почему вы потратили время, чтобы уменьшить этот ответ и опубликовать тот же запрос с той разницей. –

0

Q: Вы, кажется, моя проблема, верно?

A: Да, мы видим проблему.

В качестве одного из возможных подходов к сокращению запроса и повышению производительности мы можем использовать запрос встроенного представления для возврата MAX(speeldur) для перечисленных жанров. Результаты этого запроса получают материализованную во временную таблицу, которую MySQL называет «производной таблицей». Затем внешний запрос выполняет операцию JOIN между «производной таблицей» и таблицей film, чтобы получить соответствующие строки из film.

Обратите внимание, что в соответствии с исходным запросом нам необходимо получить MAX(speeldur) для жанра 'Ужас', но затем сопоставить это с speelduur для строк, которые имеют жанр 'Misdaad'. (Немного любопытно, что нужно сделать, но мы можем справиться с этим в предикате JOIN, без проблем.)

Если цель состоит в том, чтобы получить «все» жанр, мы можем опустить предикат WHERE g.genre IN (list) из запроса вида. Затем мы получим все возможные значения: genre.

В качестве примера такого подхода:

SELECT f.genre 
    , f.titel 
    , f.speelduur 
    FROM film f 
    JOIN (SELECT g.genre 
       , MAX(g.speelduur) AS max_speelduur 
      FROM film g 
      WHERE g.genre IN ('Actie','Avontuur','Comedie','Dans','Drama' 
          ,'Epos','Fantasie','Historisch','Horror' 
          ,'Musical','Mysterie','Oorlog','Rampen' 
          ,'Religieus','Romantiek','Science Fiction') 
      GROUP BY g.genre 
     ) m 
    JOIN film f 
    ON f.genre = IF(m.genre='Horror','Misdaad',m.genre) 
    AND f.speelduur = m.max_speelduur 

Для лучшей производительности, мы хотим иметь подходящие индексы доступны. Для этого запроса, мы ожидаем, что это будет достаточно:

... ON film (genre, speelduur) 

В качестве альтернативы, мы могли бы вместо того, чтобы определить индекс, как это:

... ON film (genre, speelduur, film) 

так, что будет «индекс покрытия» для внешний запрос.

+0

Если мы не хотим менять жанр '' Misdaad'' для жанра '' Horror '' (как показано в оригинале query), тогда мы могли бы удалить выражение 'IF()' в предикате соединения и заменить его просто «m.genre'. – spencer7593

0

Это работает в MySql 5,5

SELECT MAX(speelduur), genre 
FROM film 
where genre in ('Actie','Comedie','Dans') 
group by genre desc 

Добавьте больше жанров в зависимости от обстоятельств.

http://sqlfiddle.com/#!2/d6d7b/4

Смежные вопросы