У меня есть три таблицы; Аукционы, Аукционные Предложения и Пользователи. Структура таблицы выглядит примерно так:
Auctions:
id title
-- -----
1 Auction 1
2 Auction 2
Auction Bids:
id user_id auction_id bid_amt
-- ------- ---------- -------
1 1 1 200.00
2 2 1 202.00
3 1 2 100.00
Users
просто стандартная таблица, с идентификатором и именем пользователя.
Моя цель состоит в том, чтобы присоединиться к этим таблицам, таким образом, я могу получить самые высокие значения этих предложений, а также связывать имена пользователей с теми предложениями; таким образом, у меня есть набор результатов как так:
auction_id auction_title auctionbid_amt user_username
---------- ------------- -------------- -------------
1 Auction 1 202.00 Bidder2
2 Auction 2 100.00 Bidder1
До сих пор мой запрос следующие:
SELECT a.id, a.title, ab.bid_amt, u.display_name FROM auction a
LEFT JOIN auctionbid ab ON a.id = ab.auction_id
LEFT JOIN users u ON u.id = ab.user_id
GROUP BY a.id
Это получает единственные строки, которые я после, но это, кажется, отображает самый низкий bid_amt, не самое высокое.
Вы можете использовать функцию MAX и подвыборку, чтобы получить максимальную ставку для каждого аукциона. Если вы объедините этот подзапрос с другими своими таблицами и установите предложение where следующим образом, вы должны получить то, что ищете.
SELECT a.id, a.title, ab.bid_points, u.display_name
FROM Auction AS a
INNER JOIN (SELECT auction_id, MAX(bid_points) AS maxAmount FROM auction_bids GROUP BY auction_id) AS maxBids ON maxBids.auction_id = a.id
INNER JOIN auction_bids AS ab ON a.id = ab.auction_id
INNER JOIN users AS u ON u.id = ab.user_id
WHERE ab.auction_id = maxBids.auction_id AND ab.bid_amount = maxBids.maxAmount
Надеюсь, что это поможет.
Попробуйте следующее:
SELECT a.id, a.title, ab.bid_points, u.display_name FROM auction a
LEFT JOIN auctionbid ab ON a.id = ab.auction_id
LEFT JOIN users u ON u.id = ab.user_id
GROUP BY a.id
ORDER BY ab.bid_points DESC
Если это не сработает, попробуйте использовать подвыборку на аукционе auctionbids, содержащую что-то вроде
SELECT id, user_id, auction_id, MAX(bid_amt) FROM action_bids GROUP BY auction_id
Попробуйте добавить следующий пункт; не уверен насчет производительности.
WHERE NOT EXISTS
(SELECT * FROM auctionbid abhigher
WHERE abhigher.auction_id = ab.auction_id
AND abhigher.auctionbid_amt > ab.auctionbid_amt)
Исключает из запроса аукционные заявки, которые имеют более высокую ставку для того же аукциона.
Единственная проблема заключается в том, что если у вас есть 2 одинаковые ставки, обе будут отображаться в списке. Один из способов избавиться от них - но это относительно произвольный выбор победителя - использовать идентификатор ставки:
WHERE NOT EXISTS
(SELECT * FROM auctionbid abhigher
WHERE abhigher.auction_id = ab.auction_id
AND abhigher.auctionbid_amt >= ab.auctionbid_amt
AND abhigher.id > ab.id)
Вот что вы можете попробовать... как в старой школе... ничего нового... не нужно делать left join или что-то еще... остальное зависит от ваших точных требований
select A.id,A.title,max(AB.bid_amt),name
from Auction A,AuctionBids AB,Users U
where U.ID=AB.USER_ID AND A.ID=AB.ID
group by A.ID,A.title,name
Это типичная проблема агрегирования внутри группы. Вы можете решить ее с помощью так называемого left self exclusion join
Попробуйте сделать следующее:
SELECT a.id, a.title, ab.bid_points, u.displayname
FROM auction a
INNER JOIN auction_bids ab ON ab.auction_id = a.id
LEFT JOIN auction_bids b1 ON ab.auction_id = b1.auction_id
AND ab.bid_points < b1.bid_points
LEFT JOIN users u ON u.id = ab.user_id
WHERE b1.auction_id IS NULL
По сути, он строит объединение между левой и правой сторонами, пока не найдет больше ни одного для левой стороны, и тогда это будет самый высокий элемент.
Другим решением может быть использование нескольких запросов (конечно) или временной агрегированной таблицы.