2014-09-24 2 views
1

У меня есть таблица с billID быть первичным ключом:Альтернатива GROUP BY

Invoice (billID, item, value, quantity)

и следующий запрос:

SELECT item, sum(quantity) AS TotalItems 
FROM Invoice 
WHERE value>1 
GROUP BY item 
HAVING sum(quantity)>10 

мне нужно переписать оптимизируют (или de-optimize?) используя только SELECT, FROM и WHERE.

  1. Каков новый запрос, устраняющий GROUP BY и HAVING?
  2. Всегда можно устранить GROUP BY & HAVING и использовать только SELECT, FROM и WHERE?

Мой подход:

[1] Я использую UNION различной items для достижения этой цели. Но главная проблема в том, что мне нужно знать все item перед рукой.

SELECT item, sum(quantity) FROM Invoice WHERE item='lumia' 
UNION 
SELECT item, sum(quantity) FROM Invoice WHERE item='iphone' 
UNION 
SELECT item, sum(quantity) FROM Invoice WHERE item='samsung' 
UNION 
SELECT item, sum(quantity) FROM Invoice WHERE item='moto' 
. 
. 
. 
and so on 

Есть ли другой способ получить результат?

+0

Что случилось с вашим исходным запросом? Я думаю, что это наиболее оптимальное решение для вашей проблемы. – sgeddes

+0

@sgeddes Я согласен. Но мне нужно проанализировать запрос без 'GROUP BY' и' HAVING' – Sumit

+0

@sam: почему? Какую конкретную проблему вы пытаетесь решить? У вас проблемы с производительностью? Это интервью мозгового дразнилки? Домашнее задание? Вам просто интересно? Я не могу придумать, почему вы хотите использовать что-либо другое, кроме GROUP BY. Альтернативы, как правило, более медленные и, конечно, менее гибкие. – siride

ответ

6

мы можем использовать подзапрос и делать суммирование количества каждого элемента

SELECT A.item, A.Total 
FROM 
( SELECT distinct item, 
     (SELECT SUM(quantity) 
     FROM Invoice I2 
     WHERE I2.item = I1.item) Total 
FROM Invoice I1 
) A 
where Total >10 
+0

+1 - Мне нравится этот подход лучше, чем у меня, но я бы сказал, что он все еще использует агрегацию, которая использует 'group by' (даже если предложение' group by' опущено). – sgeddes

+0

Спасибо @Rajesh и @sgeddes. Я предполагаю, что это будет альтернативой «GROUP BY» в каждом случае, но довольно сложно писать! – Sumit

+0

Я предполагаю, что это будет иметь тот же план выполнения, что и версия «GROUP BY». – siride

1

В то время как я бы никогда рекомендую делать это таким образом, MySql не поддерживает определенные пользователем переменные. Таким образом, вы технически может переписать запрос, чтобы суммировать элементы в переменной, установить номер строки, чтобы получить максимум, а затем выбрать только самое высокое общее количество в каждой группе (за единицу):

select item, totalitems 
from (
    select 
    item, totalitems, @rn:=IF(@previtem=item,@rn+1,1) rn, @previtem:=item 
    from (
    select item, 
     @qtytotal:=(IF(@previtem=item,@qtytotal+quantity,quantity)) totalitems, 
     @previtem:=item 
    from invoice, (select @qtytotal:=0, @previtem:='') t 
    where value > 1 
    order by item 
    ) t, (select @rn:=0, @previtem:='') s 
    where totalitems > 10 
    order by item, totalitems desc 
) t 
where rn = 1 

Это написано с концепцией только с использованием select, from и where - нет агрегации, такие как sum, которые технически использует group by Wi го или без предложения.

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