У меня возникли проблемы с объединением данных из нескольких таблиц. Я попробовал соединения и подзапросы, но безрезультатно. Мне в основном нужно объединить 2 запроса в один. Мои таблицы (упрощенные):
Склад:
id int(9) PrimaryIndex
lot_number int(4)
description text
reserve int(9)
current_bid int(9)
current_bidder int(6)
Пользователи:
member_id int(11) PrimaryIndex
name varchar(255)
Предложения:
id int(9)
lot_id int(9)
bidder_id int(5)
max_bid int(9)
time_of_bid datetime
В настоящее время я использую 2 отдельных запроса, которые с 1000 лотов делают его очень неэффективным. 1-й запрос:
SELECT S.id, S.lot_number, S.description, S.reserve FROM stock S ORDER BY
S.lot_number ASC
Второй запрос в цикле while получает информацию о ставках:
SELECT DISTINCT B.bidder_id, B.lot_id, B.max_bid, B.time_of_bid,
M.fname, M.lname FROM bids B, members M WHERE B.lot_id=? AND
B.bidder_id=M.member_id ORDER BY B.max_bid DESC LIMIT 2
Ниже приводится то, что я хотел бы получить от одного запроса, если это возможно:
Lot No. | Reserve | Current Bid | 1st Max Bid | 1st Bidder | 2nd Max Bid | 2nd Max Bidder
1 | $100 | $120 | $150 | Steve | $110 | John
2 | $500 | $650 | $900 | Tom | $600 | Paul
У меня был частичный успех, просто получив MAX(B.bid)
а затем связанные с ним детали (WHERE S.id=B.id
), но я не могу получить лучшие 2 ставки для каждой партии.
Сначала присвойте номер строки rn
строкам в каждой группе lot_id
в таблице bids
(наибольшая ставка получает 1, вторая наибольшая ставка получает 2 и так далее). Самая высокая ставка и вторая по величине ставка будут на двух разных строках после LEFT JOIN
. Используйте GROUP BY
чтобы объединить две строки в одну.
select s.lot_number, s.reserve, s.current_bid,
max( case when rn = 1 then b.max_bid end) as first_max_bid,
max( case when rn = 1 then m.name end) as first_bidder,
max( case when rn = 2 then b.max_bid end) as second_max_bid,
max( case when rn = 2 then m.name end ) as second_bidder
from
stock s
left join
(select * from
(select *,
(@rn := if(@lot_id = lot_id, @rn+1,
if( @lot_id := lot_id, 1, 1))) as rn
from bids cross join
(select @rn := 0, @lot_id := -1) param
order by lot_id, max_bid desc
) t
where rn <= 2) b
on s.lot_number = b.lot_id
left join members m
on b.bidder_id = m.member_id
group by s.lot_number, s.reserve, s.current_bid
order by s.lot_number