powered by simpleCommunicator - 2.0.51     © 2025 Programmizd 02
Форумы / MySQL [игнор отключен] [закрыт для гостей] / SQL запрос на вывод максимальной ставки сделанной пользователем по каждому лоту
24 сообщений из 24, страница 1 из 1
SQL запрос на вывод максимальной ставки сделанной пользователем по каждому лоту
    #39951612
Влад67
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Есть 4 таблицы, но к запросу относятся только 3:

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
CREATE TABLE user (
id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
register_date DATETIME NOT NULL,
email VARCHAR(150) NOT NULL UNIQUE,
name VARCHAR(200) NOT NULL,
password TEXT,
contact VARCHAR(200)
);

CREATE TABLE lot (
id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
date_create DATETIME,
title VARCHAR(150),
description TEXT(5000),
img VARCHAR(250),
price INT,
date_end DATE,
step SMALLINT,
id_user INT NOT NULL,
winner INT,
id_category INT NOT NULL
);

CREATE TABLE rate (
id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
date DATETIME,
amount INT NOT NULL,
id_user INT,
id_lot INT NOT NULL
);



Нужно вывести максимальную ставку по лотам в которых закончилась дата публикации "date_end", в тоже время нету победителя "winner". Победитель определяется максимальной ставкой на момент окончания действия лота. Ставка "amount" в таблице ставок "rate". Когда будет определен победитель в столбец "winner" записывается id пользователя, который сделал наибольшую ставку. Записываться скорее всего будет уже через PHP, в отдельном запросе. То есть нужно выбрать ставку, чтобы столбец " winner " таблицы " lot " был пустым, " date_end " таблицы " lot " был меньше текущего времени и ставка " amount " таблицы " rate " была наибольшей по этому лоту.

Пока что пришел к такому запросу:

Код: sql
1.
2.
3.
4.
5.
    SELECT l.id, l.title, l.price, l.date_end, l.winner, MAX(r.amount) AS max_amount, ANY_VALUE(u.name), ANY_VALUE(u.email) FROM rate r
    JOIN lot l ON r.id_lot = l.id
    JOIN user u ON r.id_user = u.id
    WHERE l.date_end < NOW() AND l.winner IS NULL
    GROUP BY l.id



но данные из таблицы user выводятся не правильные, как будто нет связи между таблицами rate и user. Не понимаю почему. Если убрать ANY_VALUE(), то пишет ошибку, что ему не понятно какие данные выбирать.

#1055 - Expression #7 of SELECT list is not in GROUP BY clause and contains nonaggregated column 'yeticave.u.name' which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_by
...
Рейтинг: 0 / 0
SQL запрос на вывод максимальной ставки сделанной пользователем по каждому лоту
    #39951624
Gluck99
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Влад67,
Используйте форматирование кода
Код: plaintext
SRC -> sql
Вашу мелкую абракадабру тяжело читать.
...
Рейтинг: 0 / 0
SQL запрос на вывод максимальной ставки сделанной пользователем по каждому лоту
    #39951627
Влад67
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Gluck99, А тут можно отредактировать сообщение? не могу найти как
...
Рейтинг: 0 / 0
SQL запрос на вывод максимальной ставки сделанной пользователем по каждому лоту
    #39951630
Gluck99
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Влад67
Gluck99, А тут можно отредактировать сообщение? не могу найти как
Можно редактировать, но только первые, по-моему, 10 минут. Потом кнопка пропадает.
...
Рейтинг: 0 / 0
SQL запрос на вывод максимальной ставки сделанной пользователем по каждому лоту
    #39951634
Влад67
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Gluck99,

Ну теперь видимо не поменяю никак тогда. А создавать еще одну тему с тем же вопросом ну такое.
...
Рейтинг: 0 / 0
SQL запрос на вывод максимальной ставки сделанной пользователем по каждому лоту
    #39951636
miksoft
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Влад67
Gluck99,

Ну теперь видимо не поменяю никак тогда. А создавать еще одну тему с тем же вопросом ну такое.
Я поправил.
...
Рейтинг: 0 / 0
SQL запрос на вывод максимальной ставки сделанной пользователем по каждому лоту
    #39951640
Влад67
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
miksoft, Большое спасибо
...
Рейтинг: 0 / 0
SQL запрос на вывод максимальной ставки сделанной пользователем по каждому лоту
    #39951657
Gluck99
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Влад67,
1) Так у вас же inner join'ы, логично, если нет соответствия, ничего возвращено не будет.
2) Надо упростить запрос до минимума и переписать его нормально, без ANY_VALUE() - это зло в общем случае.
3) Логично что ошибку даёт, у вас записи негарантированно уникальные.
Код: sql
1.
GROUP BY r.ID
...
Рейтинг: 0 / 0
SQL запрос на вывод максимальной ставки сделанной пользователем по каждому лоту
    #39951698
Влад67
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Gluck99,
Вот я и хотел бы закрыть пробел в знаниях. Если писать
Код: plsql
1.
2.
3.
4.
5.
SELECT l.id, l.title, l.price, l.date_end, l.winner, MAX(r.amount) AS max_amount, u.name, u.email FROM rate r
    JOIN lot l ON r.id_lot = l.id
    JOIN user u ON r.id_user = u.id
    WHERE l.date_end < NOW() AND l.winner IS NULL
    GROUP BY r.id

, то выводит таблицу с лишними данными. Прикрепил изображение. Как я понял он выводит всех пользователей, которые делали ставки на эти лоты. Но я не могу понять почему. Я же вроде указываю что мне нужны только максимальные ставки. И эти максимальные ставки соотвествуют только одному пользователю.
...
Рейтинг: 0 / 0
SQL запрос на вывод максимальной ставки сделанной пользователем по каждому лоту
    #39951759
Gluck99
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Влад67,
Почему понятно - потому что группировка должна делаться по r.lot_id. Тут нужен вложенный запрос.
В связи с этим вопрос: а lot.id_user и rate.id_user содержат один и тот же идентификатор пользователя, если lot.id = rate.id_lot?
Я не могу понять как ваши таблицы соотносятся. Если rate содержит несколько записей со ссылкой на lot, то что хранит lot.id_user?
P.S. Поле winner лучше переименовать в id_winner.
...
Рейтинг: 0 / 0
SQL запрос на вывод максимальной ставки сделанной пользователем по каждому лоту
    #39951784
Влад67
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Gluck99,
Нет, lot.id_user - это id пользователя который разместил лот на сайте, а rate.id_user - это id пользователя разместившего ставку на лот.
Таблицы соотносятся так: lot.id_user - user.id - id пользователя создавшего лот. Таблица rate содержит rate.id_lot - лот по которому сделана ставка, а rate.id_user - того, кто сделал ставку. По каждому лоту может быть несколько ставок от разных пользователей.
Не могу разобраться со вложенными запросами. Сколько не читал, как понял, он выполняется и вписывает в свое место итог запроса. Что бы выполнился уже внешний запрос. Но как тогда мне нужно изменить запрос, что бы он выполнился? Как понять, что нужен именно вложенный запрос?
Вы сказали, что у меня таблица user не соотносится из-за того, что используются INNER JOIN, но почему тогда все равно выводятся данные из таблицы user? Я пробовал другие типы JOINов и ничего не получалось.
...
Рейтинг: 0 / 0
SQL запрос на вывод максимальной ставки сделанной пользователем по каждому лоту
    #39951795
mini.weblab
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
а почему вы не решаете проблему через SQL + PHP?
имхо, это проще и читабельнее в смысле кода.
потом будете читать вложенный запрос, ругаться. зачем?

Логика такая:
1) находим лоты, где дата меньше текущей и победитель отсутствует, получаем массив объектов типа лот.
(таблица lot)

Цикл
2) для каждого лота из полученного массива находим id пользователя, сделавшего максимальную ставку по лоту.
(таблица rate)
3) вытаскиваем данные по пользователю из таблицы user
Конец цикла
...
Рейтинг: 0 / 0
SQL запрос на вывод максимальной ставки сделанной пользователем по каждому лоту
    #39951804
Фотография Akina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
1) Укажите точно версию MySQL.
2) Дайте пример наполнения таблиц, участвующих в процессе, в формате INSERT INTO. В теге SRC.
3) Дайте эталонный результат для именно такого наполнения - в теге Table (разделитель полей - запятая), с пояснением, почему именно так.

Перед публикацией проверьте, что теги проставлены верно, кнопкой Просмотр.
...
Рейтинг: 0 / 0
SQL запрос на вывод максимальной ставки сделанной пользователем по каждому лоту
    #39951805
Gluck99
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Влад67,
Теперь вроде понятно полностью.
Болванка вот такая:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
SELECT rt.id_lot, rt.max_amount, r.id_user, r.name, r.email
  FROM
  (SELECT rt1.id_lot, MAX(rt1.amount) AS max_amount
    FROM rate rt1
    GROUP BY  rt1.id_lot) rt

  LEFT JOIN (SELECT u.name, u.email, r3.id_lot, r3.amount FROM rate r3 LEFT JOIN user u ON u.id = r3.id_user) r 
               ON  r.id_lot = rt.id_lot AND rt.max_amount = r.amount


Пришлось связываться через amount, что не очень хорошо, но другого простого выхода тут нет. Т.е. запрос должен вываливать id, имя юзера и его почту, без учета даты лота и значения поля winner.

Я строго рекомендую руководствоваться общепринятыми неформальными правилами в именовании таблиц и полей:
1) Имена таблиц во множественном числе: lots, users, rates. Имена полей в единственном.
2) Не использовать служебные слова: user, date, name и т.д.
3) Не бойтесь использовать длинные (исчерпывающие) имена таблиц и полей.
Когда-нибудь у вас из-за несоблюдения этих простых правил, особенно второго, очень крупно подгорит. Поэтому пока БД небольшая, лучше исправить.
...
Рейтинг: 0 / 0
SQL запрос на вывод максимальной ставки сделанной пользователем по каждому лоту
    #39952117
Влад67
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Gluck99,
Большое спасибо за рекомендации. Пишет
Код: plsql
1.
#1054 - Неизвестный столбец 'r.id_user' в 'field list'


Не смог полностью разобраться во вложенных запросах. Хотелось бы понять их логику.
Вы можете порекомендовать литературу, для изучения этого вопроса?
...
Рейтинг: 0 / 0
SQL запрос на вывод максимальной ставки сделанной пользователем по каждому лоту
    #39952118
Влад67
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
mini.weblab,
Не хочется разделять один запрос на несколько частей. Не функционально. Хотелось поиск нужных данных полностью возложить на SQL.
...
Рейтинг: 0 / 0
SQL запрос на вывод максимальной ставки сделанной пользователем по каждому лоту
    #39952120
Влад67
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Akina,
1 MYSQL 5.7 x64
2
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
INSERT INTO categories (name, code)
VALUES
    ('Доски и лыжи', 'boards'),
    ('Крепления', 'attachment'),
    ('Ботинки', 'boots'),
    ('Одежда', 'clothing'),
    ('Инструменты', 'tools'),
    ('Разное', 'other');

INSERT INTO user (register_date, email, name, password, contact)
VALUES
    ('2019-11-10 12:11:10', 'asd@gmail.com', 'Иван', '12345', '89548565474'),
    ('2018-05-13 18:40:17', 'billibob@gmail.com', 'Билл', '54321', '89254758569'),
    ('2019-03-25 01:15:36', 'robinzon@gmail.com', 'William', 'qwerty', '89658742365'),
    ('2019-01-29 23:00:00', 'asicomo@mail.ru', 'Александр', '657714', '89875248595'),
    ('2018-12-05 18:55:13', 'vromfjl@gmail.com', 'Силиван', 'sdiufeeff', '89246887158'),
    ('2019-05-26 05:38:45', 'linialius@gmail.com', 'Анастасия', 'sadfdfs', '89532587459');

INSERT INTO lot (date_create, title, description, img, price, date_end, step, id_user, id_category)
VALUES
    ('2019-11-14 11:20:14', '2014 Rossignol District Snowboard', 'Сноуборд DISTRICT AMPTEK от ...','img/lot-1.jpg', '10999', '2019-11-14', '200', '1', '1'),
    ('2019-10-21 18:12:36', 'DC Ply Mens 2016/2017 Snowboard', 'Легкий маневренный сноуборд, ...', 'img/lot-2.jpg', '15999', '2020-03-10', '300', '2', '1'),
    ('2019-05-11 17:29:01', 'Крепления Union Contact Pro 2015 года размер L/XL', 'Невероятно легкие универсальные ...', 'img/lot-3.jpg', '8000', '2020-01-21', '150', '1', '2'),
    ('2019-08-02 01:17:47', 'Ботинки для сноуборда DC Mutiny Charcoal', 'Эти ботинки созданы для ...', 'img/lot-4.jpg', '10999', '2019-12-27', '250', '4', '3'),
    ('2019-09-29 12:36:11', 'Куртка для сноуборда DC Mutiny Charcoal', 'Прочный материал, ...', 'img/lot-5.jpg', '10999', '2019-12-31', '300', '6', '4'),
    ('2019-11-17 22:11:45', 'Маска Oakley Canopy', 'Увеличенный объем ... ', 'img/lot-6.jpg', '5500', '2019-12-30', '200', '4', '6');

INSERT INTO rate (date, amount, id_user, id_lot)
VALUES
    ('2019-10-15 21:17:10', '12000', '5','1'),
    ('2019-11-18 11:10:25', '6000', '3','6'),
    ('2019-11-10 13:22:46', '8500', '2','3');


3 ну тут заполнение и так видно во 2 пункте.
...
Рейтинг: 0 / 0
SQL запрос на вывод максимальной ставки сделанной пользователем по каждому лоту
    #39952131
Gluck99
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Влад67
Большое спасибо за рекомендации. Пишет
#1054 - Неизвестный столбец 'r.id_user' в 'field list'
Пардон, потерялось поле по пути. Вот это должно работать:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
SELECT rt.id_lot, rt.max_amount, r.id_user, r.name, r.email
  FROM
  (SELECT rt1.id_lot, MAX(rt1.amount) AS max_amount
    FROM rate rt1
    GROUP BY  rt1.id_lot) rt

  LEFT JOIN (SELECT r3.id_user, u.name, u.email, r3.id_lot, r3.amount FROM rate r3 LEFT JOIN user u ON u.id = r3.id_user) r 
               ON  r.id_lot = rt.id_lot AND rt.max_amount = r.amount


Вы если данные приводите, приводите с ID, иначе нет смысла, при вставке теряется целостность данных.

P.S. Литературы достаточно в сети. Просто гуглите и проделываете простое упражнение: прочитали материал - повторили то, что там написано. Набейте какую-нибудь тестовую базу и тренируйтесь. Есть очень неплохой сайт http://www.sql-ex.ru, там обучение в виде упражнений по темам от простейшего к сложному. Просто, полезно, и вы уже через несколько дней почувствуете рост уровня понимания.
...
Рейтинг: 0 / 0
SQL запрос на вывод максимальной ставки сделанной пользователем по каждому лоту
    #39952140
Фотография Akina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Проверяй:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
SELECT lll.id, 
       lll.title, 
       lll.price, 
       lll.date_end, 
       lll.winner,
       rr.amount, 
       uu.name,
       uu.email
FROM rate rr
JOIN ( SELECT l.id, MAX(r.amount) amount
       FROM rate r
       JOIN lot l ON r.id_lot = l.id
       GROUP BY l.id ) ll ON (ll.id, ll.amount) = (rr.id_lot, rr.amount)
JOIN lot lll ON rr.id_lot = lll.id
JOIN user uu ON rr.id_user = uu.id;



Подробнее - тут: fiddle . Там же кое-какие пояснения.

PS. Использовал версию 8, ибо 5.7 что-то не работает. Но никаких специфичных для 8+ конструкций там нет.

offtop
Gluck99
Есть очень неплохой сайт http://www.sql-ex.ru, там обучение в виде упражнений по темам от простейшего к сложному. Просто, полезно, и вы уже через несколько дней почувствуете рост уровня понимания.
Сайт - говно голимое. Это надо было уметь - изгадить отличную идею совершенно дебильными структурами! Если человек не освоил хотя бы основы нормальных форм и анализа - туда лучше не соваться, а то под впечатлением этого бреда они таких монстров начинают рожать!
...
Рейтинг: 0 / 0
SQL запрос на вывод максимальной ставки сделанной пользователем по каждому лоту
    #39953863
Влад67
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Gluck99,
К сожалению выводит не правильный ответ.
Есть лоты у которых срок действия не окончился еще
...
Рейтинг: 0 / 0
SQL запрос на вывод максимальной ставки сделанной пользователем по каждому лоту
    #39953864
Влад67
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Akina,
Судя по сайту fiddl Там вроде запрос верный. Но у меня он выводит данные с лотами, у которых еще не кончился срок действия.
...
Рейтинг: 0 / 0
SQL запрос на вывод максимальной ставки сделанной пользователем по каждому лоту
    #39953883
Gluck99
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Влад67
Gluck99,
К сожалению выводит не правильный ответ.
Есть лоты у которых срок действия не окончился еще
Я же написал - отбора по лотам у меня в запросе просто нет. Можете добавить сами и отладить у себя.
...
Рейтинг: 0 / 0
SQL запрос на вывод максимальной ставки сделанной пользователем по каждому лоту
    #39964470
Влад67
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Нашел решение, пришлось глубже изучать язык, для более полного понимания. Всем спасибо.

Код: sql
1.
2.
3.
4.
5.
6.
SELECT lot.id, lot.title, lot.price, lot.date_end, lot.winner, rate.date, rate.amount, user.name, user.email FROM lot
JOIN (SELECT * FROM rate
    WHERE amount IN (SELECT MAX(amount) AS max_amount FROM rate
    GROUP BY id_lot)) AS rate ON lot.id = rate.id_lot
JOIN user ON lot.id_user = user.id
WHERE lot.date_end < NOW()
...
Рейтинг: 0 / 0
SQL запрос на вывод максимальной ставки сделанной пользователем по каждому лоту
    #39964591
miksoft
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Влад67
Код: sql
1.
amount IN (SELECT MAX(amount)

Вот это явно неправильно.
Если в одной группе максимальный amount совпадет с не максимальным в другой, то тот тоже попадет в результат.
...
Рейтинг: 0 / 0
24 сообщений из 24, страница 1 из 1
Форумы / MySQL [игнор отключен] [закрыт для гостей] / SQL запрос на вывод максимальной ставки сделанной пользователем по каждому лоту
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]