|
|
|
| Здравствуйте!
Имеются 2 таблицы:
1) Таблица USERS
CREATE TABLE `users` (
`id` INT NOT NULL ,
`name_surname` VARCHAR( 30 ) NOT NULL
);
2) Таблица ORDERS
CREATE TABLE `orders` (
`id` INT NOT NULL ,
`user_id` INT NOT NULL ,
`order_value` INT NOT NULL ,
`value_paid` INT NOT NULL
);
order_value=СТОИМОСТЬ ЗАКАЗА
value_paid=СКОЛЬКО УЖЕ ОПЛАЧЕНО
user_id=ID пользователя совершившего заказ
Требуется одним запросом вытащить имя_фамилия, к-во оплаченных заказов, сколько ВСЕГО денег заплачено за все заказы.
Поясненние: определение того оплачен заказ или нет обязательно определяется равнеством полей orders.order_value=orders.value_paid
Не понимаю куда можно влепить это условие к order_count
По другому - вычисление order_count производить в том случае ЕСЛИ ЦЕНА ЗАКАЗА совпадает С ОПЛАЧЕННОЙ ЦЕНОЙ
select users.name_surname AS name_surname, sum(orders.value_paid) AS value_paid, count(orders.id) AS order_count FROM users LEFT JOIN orders ON orders.user_id=users.id GROUP BY users.name_surname ASC HAVING users.id=1
операторы запроса желательно не менять, дабы потом чтобы можно было производить MYSQL сортировку по всем вытащенным полям.
СПАСИБО! | |
|
|
|
|
|
|
|
для: Борис
(27.10.2007 в 17:06)
| | можно задать вопрос если можно , непойму для чего там используется HAVING users.id=1,
как я понял HAVING делает то-же что WHERE , но только после поиска в таблице и перед
выдачей результата . или я неправильно понял ?
я-бы попробовал наверное так
SELECT users.name_surname AS name_surname, SUM(orders.value_paid) AS value_paid, COUNT(orders.id) AS order_count
FROM users LEFT JOIN orders ON orders.user_id=users.id
WHERE users.id=1 AND orders.order_value=orders.value_paid
GROUP BY users.name_surname ASC ;
|
и там может быть несколько одинаковых users.id ? | |
|
|
|
|
|
|
|
для: EXP
(27.10.2007 в 18:20)
| | HAVING в этом случаем заменяет WHERE - это верно. Но в данном случае нельзя использовать WHERE т.к используется оператор GROUP BY. А оператор GROUP BY в свою очередь необходим, когда происходит выборка данных единственных строк в паре с функциями которые обходят все строки таблицы после чего и делают расчёты(SUM(), COUNT()). Одинаковые USER.id могут быть лишь в таблице "заказы".
В Вашем варианте когда условие будет находить строки где совпадает id пользователя, и сумма оплаченная = сумме стоимости заказа, мне же необходимо в любом случае выбирать все строки, т.е. выводить на экран всех пользователей, и помимо этот высчитать сколько провёл полностью оплаченных заказов каждый пользователь. Чтобы позже можно было применить GROUP BY order order_coun DESC к примеру. | |
|
|
|
|
|
|
|
для: Борис
(27.10.2007 в 19:27)
| | почему-то нигде не нашёл подтверждения тому что WHERE нельзя использовать перед GROUP BY
у меня с WHERE работает что-то похожее на тысячную долю секунды быстрее чем с HAVING, если не показалось.
вам наверное придётся делать подзапрос в запросе, если COUNT и SUM считают при разных условиях. что-то похожее на это
SELECT (@id := users.id ) AS id, users.name_surname ,
SUM(orders.value_paid) AS value_paid,
( SELECT COUNT(id) FROM orders WHERE id= @id AND order_value=value_paid ) AS order_count
FROM users LEFT JOIN orders ON orders.user_id=users.id
GROUP BY users.name_surname ASC ;
| только HAVING совсем убрал и добавилось id, без переменной не пробовал так делать | |
|
|
|
|
|
|
|
для: EXP
(27.10.2007 в 20:34)
| | SELECT (
@id:= users.id
) AS id, users . name_surname , sum( orders.value_paid ) AS value_paid, (
SELECT COUNT( id )
FROM orders
WHERE orders.user_id = @id
AND orders.order_value = orders.value_paid
) AS order_count
FROM users
LEFT JOIN orders ON orders.user_id = users.id
GROUP BY name_surname DESC
Все верно всё считается правильно. Но возможность отсортировать по order_count пропадает в случае GROUP BY order_count DESC
По поводу GROUP BY и HAVING
http://www.dzmrianinaski.myweb.ge/sql_groupby.asp-output=print.htm | |
|
|
|
|
|
|
|
для: Борис
(27.10.2007 в 21:34)
| | ORDER BY order_count DESC нормально сортирует вроде
а GROUP BY так и так не группирует по значениям получаемым COUNT() или sum(),
возможно недопонимаю просто чегото , но там тоже написано что просто HAVING может работать с теми значениями которые получаются только в процессе получения и поэтому с ними не может работать WHERE
мне почему-то так думается :) | |
|
|
|
|
|
|
|
для: EXP
(27.10.2007 в 22:54)
| | Мдяя=) что-то я полез не в ту степь. Правда ведь всё решается подзапросами без всякиз лефт-джойнов....В любом случае спасибо за помощь... | |
|
|
|
|
|
|
|
для: Борис
(27.10.2007 в 21:34)
| | Спасибо Вам. я тут какраз мучался мыслью какое-же ещё бывает WHERE кроме WHERE :)
насчёт LEFT JOIN даже незнаю , может и быстрее будет с ним работать , какая-то всёравно связка двух таблиц , как-бы даже GROUP BY здесь лишняя , но без неё нельзя. только опытным путём наверное выяснить можно как будет быстрее. | |
|
|
|
|
|
|
|
для: EXP
(28.10.2007 в 01:15)
| | Борис и EXP ваша задача тривиальна:
SELECT max(u.name_surname), sum(ifnull(o.value_paid, 0)), count(o.id) AS c_num
FROM users AS u LEFT JOIN orders AS o
ON (u.id = o.user_id AND o.value_paid = o.order_value)
GROUP BY u.id
ORDER BY c_num DESC;
|
Скажу только, что в GROUP BY никаких DESC и ASC в помине нет, данные кляузы только в ORDER BY | |
|
|
|
|
|
|
|
для: oradev
(28.10.2007 в 10:49)
| | Так в догонку, решилась проблема с ORDER BY, далее при разработке возникла новая проблема. Если подставляю условие WHERE к подзапросу выдаётся ошибка. Как задать условие where к результатам подзапроса? Спасибо!
SELECT (
@this_id := users.id
) AS this_id, users . * ,
(
SELECT SUM( value_paid )
FROM orders
WHERE id = @this_id
) AS value_paid
FROM users
WHERE value_paid >=1000
ORDER BY id DESC
LIMIT 0 , 30 | |
|
|
|
|
|
|
|
для: Борис
(28.10.2007 в 19:10)
| | Борис, вы мой запрос запускали ? | |
|
|
|
|
|
|
|
для: oradev
(28.10.2007 в 19:31)
| | Да огромное спасибо, вот оно - именно то что я и искал, изящное решение в один запрос.
Но всё же интересно как решить предыдущую проблему, к чему необходимо привязать условие!?
SELECT u .name_surname , sum( ifnull( o.value_paid, 0 ) ) AS value_paid, count( o.id ) AS order_count
FROM users AS u
LEFT JOIN orders AS o ON ( u.id = o.user_id
AND o.value_paid = o.order_value )
WHERE o.value_paid >15000
GROUP BY u.id
ORDER BY order_count DESC
LIMIT 0 , 30 | |
|
|
|
|
|
|
|
для: Борис
(28.10.2007 в 20:46)
| | Хммм, теперь хочу получить помимо к-ва оплаченных заказов, к-во общих заказов не зависимо от o.value_paid = o.order_value, делаю дополнительную связь в итоге получается билиберда...
SELECT u .name_surname, sum( ifnull( o.value_paid, 0 ) ) AS value_paid, count( o.id ) AS order_paid, count( o2.id ) AS order_count
FROM users AS u
LEFT JOIN orders AS o ON ( u.id = o.user_id
AND o.value_paid = o.order_value )
LEFT JOIN orders AS o2 ON ( u.id = o2.user_id )
GROUP BY u.id
ORDER BY id DESC | |
|
|
|
|
|
|
|
для: Борис
(28.10.2007 в 21:17)
| | Также, если данный запрос возвращает верные данные
SELECT u .name_surname, sum( ifnull( o.value_paid, 0 ) ) AS value_paid, count( o.id ) AS order_paid
FROM users AS u
LEFT JOIN orders AS o ON ( u.id = o.user_id
AND o.value_paid = o.order_value )
WHERE value_paid>1000
GROUP BY u.id
ORDER BY id DESC
То следующий запрос возвращает ошибку:
SELECT u .name_surname, sum( ifnull( o.value_paid, 0 ) ) AS value_paid, count( o.id ) AS order_paid
FROM users AS u
LEFT JOIN orders AS o ON ( u.id = o.user_id
AND o.value_paid = o.order_value )
WHERE order_paid>1
GROUP BY u.id
ORDER BY id DESC
#1054 - Unknown column 'order_paid' in 'where clause' | |
|
|
|
|
|
|
|
для: Борис
(28.10.2007 в 21:34)
| | Борис, все элементарно выполняется скажите условие
Что означает - где стоимость заказа конкретного! > 1000 для пользователя
или общая уже сумма заказов пользователя.
Скажите, как трактовать, я вам напишу запрос ! | |
|
|
|
|
|
|
|
для: oradev
(28.10.2007 в 21:50)
| | 1) WHERE value_paid>1000 где общая сумма заказов пользователя больще 1000
2) WHERE order_paid>1 где к-во оплаченных заказов больше одного
3) WHERE order_count>1 где к-во заказов больше одного(не важно оплаченных или нет)
P.S (order_count ) не знаю как вытащить к-во заказов(не важно оплаченных или нет) в связке с оплаченной суммой пользователя и к-вом оплаченных заказов
P.P.S. Оффтоп, хотелось бы узнать название толкового туториала по SQL, MYSQL где теория подверждается примерами(кроме официально мануала), рыть гугл в решении данной задачи для меня гиблое дело..=(. | |
|
|
|
|
|
|
|
для: Борис
(28.10.2007 в 22:03)
| | SELECT u .name_surname, sum( ifnull( o.value_paid, 0 ) ) AS value_paid, count( o.id ) AS order_paid
FROM users AS u
LEFT JOIN orders AS o ON ( u.id = o.user_id
AND o.value_paid = o.order_value )
GROUP BY u.id
HAVING order_paid>1
AND value_paid>1000
ORDER BY id DESC
проблема с условиями для sum, count решилась используя HAVING, осталось вытащить к-во сделанных заказов(не важно оплаченных или нет). | |
|
|
|
|
|
|
|
для: Борис
(28.10.2007 в 22:03)
| | Борис, ваш запрос:
SELECT u.name_surname,sum(o.value_paid)/count(distinct o2.id) AS sum_oplaty, count(DISTINCT o
.id) AS cn_order_paid,count(DISTINCT o2.id)AS cn_order
FROM users AS u LEFT JOIN orders AS o
ON (u.id = o.user_id AND o.value_paid = o.order_value)
LEFT JOIN
orders AS o2
ON (u.id = o2.user_id)
GROUP BY u.id,u.name_surname
HAVING sum_oplaty > 1000 and cn_order_paid > 1 and cn_order > 1;
|
Что не ясно, обращайтесь поясню. | |
|
|
|
|
|
|
|
для: oradev
(29.10.2007 в 09:52)
| | Спасибо теперь всё идеально=). Вопросов нету, хотя были - но уже проштудировал материал про устранение дублирования. | |
|
|
|