[MySQL] Помогите составить запрос

Corrector

Установлен MySQL версии 4.0.26, обновить до более нового нет возможности.
Есть таблица Sales (CustomerID, Summ типа




















CustomerIDSumm

1
200

1
100

2
300

2
500

3
50


Нужно составить хитрый запрос, который бы возвращал в результате эту же таблицу, но с новой колонкой TotalSumm (сумма всех Summ с указанным CustomerID). Т.е. для вышеприведенной таблицы должен возвращать




















CustomerIDSummTotalSumm

1
200300

1
100300

2
300800

2
500800

3
5050


Как это сделать? (в версии 4.0.26 нет вложенных Select-ов).

klyv

Временной таблицей?

Sharp

Мне казалось, что даже 4.0 уже умел join-ить таблицу с subquery.
то есть что-то типа

select * from sales left join
(select customerid, sum(summ) as total group by customerid) totalsum
on sales.customerid = totalsum.customerid

должно работать.

Corrector

select * from sales left join
(select customerid, sum(summ) as total group by customerid) totalsum
on sales.customerid = totalsum.customerid

Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 4 to server version: 4.0.26-nt-max

Type 'help;' or '\h' for help. Type '\c' to clear the buffer.

mysql> select * from sales left join (select customerid, sum(summ) as total grou
p by customerid) as totalsum on sales.customerid = totalsum.customerid;

ERROR 1064 (00000): You have an error in your SQL syntax. Check the manual that
corresponds to your MySQL server version for the right syntax to use near 'sele
ct customerid, sum(summ) as total group by customerid) as t

Sharp

Ну не обязательно бездумно передирать, можно самому посмотреть и увидеть, где ошибка:

select * from sales left join
(select customerid, sum(summ) as total from sales group by customerid) totalsum
on sales.customerid = totalsum.customerid

вот правильный вариант, должен работать.

Corrector

не работает, та же самая ошибка. ну нету вложенных селектов в 4-той версии.

Sharp

Ах да, subquery появились только в 4.1.
Вот два решения с dev.mysql.com :
For more complicated subqueries, you can often create temporary tables to hold the subquery
и
The first option is to upgrade to MySQL 4.1
http://dev.mysql.com/doc/refman/4.1/en/rewriting-subqueries....

tokuchu

ну нету вложенных селектов в 4-той версии.
Вроде как для любого вложенного запроса можно построить эквивалентный join. С агрегатами может и не всегда (не думал над этим но у меня вот такой запрос в постгресе работает:
SELECT ab.id,b.sum,sum(a.sum) FROM test AS a,test AS b WHERE a.id=b.id GROUP BY b.id,b.sum;

Sharp

Жесть. Я уж очень привык к join-у и не могу без него (да и вообще у постгрес-а много вкусностей).
Но респект за такой запрос, я даже не сразу понял что он делает :)

katrin2201

Я уж очень привык к join-у и не могу без него

SELECT ab.id,b.sum,sum(a.sum)
FROM test AS a
JOIN test AS b ON (a.id=b.id) GROUP BY b.id,b.sum;

фишка приджойнивания таблицы самой к себе древняя, к постгресу отношения не имеет, и описана по-моему где-то там еще у дейта
по поводу без джойнов - в оракле долгое время слова то такого join не было

klyv

да, с агрегатами тоже должно работать это утверждение.
респект.

klyv

в оракле долгое время слова то такого join не было
а что же было?

katrin2201

а чем отличается
select from a, b where a.id=b.id

от
select from a join b on (a.id=b.id)

?

tokuchu

Я уж очень привык к join-у и не могу без него
Ну так это и есть JOIN только обыкновенный. :)

Sharp

С join-ом сначала бы отработал агрегирующий запрос, а потом бы шла связка по customerid.
В твоем же варианте сначала идет связка по customerid, а потом агрегация.
У меня мозги работают только первым способом, а до второго варианта я бы не додумался.
(да и вообще, я сетевой администратор, а SQL использую для упрощения некоторой рутины)

tokuchu

С join-ом сначала бы отработал агрегирующий запрос, а потом бы шла связка по customerid.
В твоем же варианте сначала идет связка по customerid, а потом агрегация.
ХЗ. Я всегда думал, что JOIN (если не всякие типа LEFT или RIGHT то это просто другая форма записи того, что я написал. И думаю, что то как это будет выполняться зависит от движка базы данных. Хотя я могу заблуждаться.
У меня мозги работают только первым способом, а до второго варианта я бы не додумался.
(да и вообще, я сетевой администратор, а SQL использую для упрощения некоторой рутины)
Я тоже в основном администратор, а SQL вообще почти не использую на практике пока. :grin:

katrin2201

С join-ом сначала бы отработал агрегирующий запрос, а потом бы шла связка по customerid.
В твоем же варианте сначала идет связка по customerid, а потом агрегация.
почему?
тынц

hwh2010

а что же было?
в oracle есть конструкция вида where a = b (+ что означает то ли левый то ли правый джойн

hwh2010

SELECT ab.id,b.sum,sum(a.sum) FROM test AS a,test AS b WHERE a.id=b.id GROUP BY b.id,b.sum;
следует помнить, что такой запрос будет работать некорректно при наличии в таблице одинаковых строк. возможность наличия таких строк отвергается теорией реляционных СУБД, но на практике, естественно, допускается (в PostgreSQL по крайней мере)

SCIF32

в каком месте реляционной алгебры уникальность кортежей требуется?
часто ты не уникальные поля называешь "id" ?

Sharp

Посмотри внимательней на таблицу в начальном посте — там customerid нисколько не уникален.
По хорошему надо добавить какой-нить уникальное поле типа sale_id и тогда все будет хорошо.

SCIF32

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

Sharp

А если насчет уникальности, то, например, здесь это утверждается: http://ru.wikipedia.org/wiki/%D0%E5%EB%FF%F6%E8%EE%ED%ED%E0%... А здесь http://ru.wikipedia.org/wiki/%CD%EE%F0%EC%E0%EB%FC%ED%E0%FF_... это требуется даже перед определением первой нормальной формы.

klyv

СУБД предоставляет максимум возможностей. пользователь решает, будет у него первая форма или нет :)
Оставить комментарий
Имя или ник:
Комментарий: