#mysql
#mysql
Вопрос:
У меня возникли небольшие проблемы при попытке уменьшить избыточность запроса в MySQL. В настоящее время у меня это работает, но мне кажется, что у меня слишком много накладных расходов, потому что он использует избыточный подзапрос. Что я пытаюсь сделать, так это использовать базу данных проката DVD, чтобы найти, в каком магазине было арендовано больше DVD-дисков за каждый месяц в 2005 году.
Вот рабочий запрос
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». Я не уверен, есть ли способ избавиться от этого, поскольку я не могу выполнить внутреннее соединение с псевдонимом. Я просто застрял с гигантским запросом, или есть что-то еще, что я могу сделать?
Комментарии:
1. MySQL 8 (в настоящее время в бета-версии) будет реализовывать общие табличные выражения, так что вы сможете делать это в будущем с меньшей избыточностью. Или вы могли бы переключиться на PostgreSQL или любую другую базу данных SQL.
2. Как насчет
CREATE TEMPORARY TABLE IF NOT EXISTS invent AS (SELECT [subquery SQL here])
того, чтобы затем присоединиться кinvent
(и отбросить в конце)?3. Теперь, глядя на ваш код, я думаю, что его можно переписать с помощью
CASE
… позвольте мне попробовать…
Ответ №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
Дайте мне знать, как это происходит!
Редактировать: чтобы ответить на вопрос, в каком магазине было арендовано больше 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
Я был откровенен, используя псевдонимы везде, вы, вероятно, могли бы опустить некоторые. Надеюсь, это поможет…
Редактировать: грязный взлом:
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
Ссылка:
http://kristiannielsen.livejournal.com/6745.html
Но тогда это удовлетворяет вас, поскольку у вас уже есть рабочий запрос…
Комментарии:
1. Этот запрос такой же, как мои подзапросы a amp; c. Это было бы правильно, если бы он возвращал только месяц, хранилище и количество для хранилища с наибольшим количеством арендуемых в месяц, чего я и пытаюсь достичь выше. Технически, вы действительно можете легко определить, какой магазин арендовал больше в месяц из этой таблицы, но это не совсем то, для чего мне нужен запрос.
2. Ах, я только что опубликовал правку, но позвольте мне прочитать ваш комментарий, чтобы узнать, обращается ли он к ней…
3. Я полагаю, что редактирование касается комментария и намерения?
4. используя x.store_id в предложении group by, этот запрос возвращает точно такой же результат, как и первый. Однако без этого вернутся месяцы и максимальное количество арендованных, но неправильное хранилище.
5. Спасибо, это очень интересная проблема, ссылка хорошо справляется с обсуждением решений и их сроков.