2016-10-18 3 views
1

У меня возникли проблемы с уменьшением избыточности запроса в MySQL. В настоящее время у меня это работает, но мне кажется, что у меня слишком много накладных расходов, потому что он использует избыточный подзапрос. То, что я пытаюсь сделать, это использовать базу данных аренды DVD, чтобы узнать, какой магазин место арендовала более DVD, за каждый месяц в 2005 годуМинимизация избыточности MySQL-запроса

Вот это рабочий запрос,

SELECT b.month, c.store_id, b.maxRentals 
FROM 
    (SELECT a.month, MAX(a.rentalCount) as maxRentals 
    FROM 
     (SELECT MONTH(rental.rental_date) as month, inventory.store_id, count(1) as rentalCount 
     FROM rental 

     INNER JOIN inventory 
     ON rental.inventory_id = inventory.inventory_id 

     WHERE YEAR(rental.rental_date) = 2005 

     GROUP BY MONTH(rental.rental_date), inventory.store_id 
     ) a 
    GROUP BY a.month 
    ) b 

    INNER JOIN 

    (SELECT MONTH(rental.rental_date) as month, inventory.store_id, count(1) as rentalCount 
    FROM rental 

    INNER JOIN inventory 
    ON rental.inventory_id = inventory.inventory_id 

    WHERE YEAR(rental.rental_date) = 2005 

    GROUP BY MONTH(rental.rental_date), inventory.store_id 
    ) c 
ON b.maxRentals = c.rentalCount 

GROUP BY b.month; 

Обратите внимание, как подзапрос с псевдоним «c» - это тот же подзапрос псевдонима «a». Я не уверен, есть ли способ избавиться от этого, так как я не могу присоединиться к псевдониму. Я просто застрял в гигантском запросе, или есть что-то еще, что я могу сделать?

+0

MySQL 8 (в настоящее время в бета-версии) реализует Common Table Expressions, поэтому вы сможете сделать это в будущем с меньшим избыточным объемом. Или вы можете переключиться на PostgreSQL или любую другую базу данных SQL. –

+0

Как насчет 'CREATE TEMPORARY TABLE, ЕСЛИ НЕ СУЩЕСТВУЕТ ИСПОЛЬЗОВАТЬ AS (SELECT [subquery SQL здесь])', затем присоединяться к 'invent' (и падать в конце)? – Eugene

+0

Теперь, глядя на ваш код, я думаю, что его можно переписать с помощью 'CASE' ... позвольте мне пойти ... – Eugene

ответ

1

Я 90% уверен, этот запрос будет достичь своих намерений:

SELECT MONTH(r.rental_date), i.store_id, COUNT(*) 
FROM rental r 
LEFT JOIN inventory i ON r.inventory_id = i.inventory_id 
WHERE YEAR(r.rental_date) = 2005 
GROUP BY MONTH(r.rental_date), i.store_id 

Позвольте мне знать, как она идет!

Edit: ответить на вопрос который магазин расположение арендовала более DVD, за каждый месяц в 2005:

SELECT x.rental_month, x.store_id, MAX(x.rental_count) FROM (
SELECT MONTH(r.rental_date) AS rental_month, i.store_id AS store_id, COUNT(*) AS rental_count 
FROM rental r LEFT JOIN inventory i ON r.inventory_id = i.inventory_id 
WHERE YEAR(r.rental_date) = 2005 
GROUP BY MONTH(r.rental_date), i.store_id) x 
GROUP BY x.rental_month, x.store_id 

Я был явно с помощью алиасов везде, вы могли бы, вероятно, опускаем некоторые. Надеюсь, что это помогает ...

Edit: Грязный хак:

SELECT x.rental_month, x.store_id, MAX(x.rental_count) FROM (
SELECT MONTH(r.rental_date) AS rental_month, i.store_id AS store_id, COUNT(*) AS rental_count 
FROM rental r LEFT JOIN inventory i ON r.inventory_id = i.inventory_id 
WHERE YEAR(r.rental_date) = 2005 
GROUP BY MONTH(r.rental_date), i.store_id 
ORDER BY MONTH(r.rental_date) ASC, COUNT(*) DESC) x 
GROUP BY x.rental_month 

Ref: http://kristiannielsen.livejournal.com/6745.html

Но тогда же это удовлетворит вас, видя, как вы уже есть рабочий запрос .. .

+0

Этот вопрос совпадает с моими подзапросами a & c. Это было бы правильно, если бы он возвращал месяц, хранилище и подсчитывал для магазина с самой арендой в месяц, чего я пытаюсь достичь выше. Технически вы действительно можете легко сказать, какой магазин арендован больше за месяц из этой таблицы, но это не совсем то, что мне нужно для выполнения запроса. – user2789945

+0

А, я только что опубликовал редактирование тем временем, но позвольте мне прочитать ваш комментарий, чтобы узнать, обращается ли он ... – Eugene

+0

Я считаю, что редактирование касается комментариев и намерений? – Eugene

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