Получение 2 лучших заявок по каждому предмету на аукционе

0

У меня возникли проблемы с объединением данных из нескольких таблиц. Я попробовал соединения и подзапросы, но безрезультатно. Мне в основном нужно объединить 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 ставки для каждой партии.

  • 0
    Не могли бы вы создать пример базы данных на www.sqlfiddle.com и поделиться ссылкой здесь?
  • 0
    Привет, cdaiga, я попытался создать то, что ты просил здесь: sqlfiddle.com/#!9/658272, дайте мне знать, если это поможет.
Теги:
join
subquery

1 ответ

0
Лучший ответ

Сначала присвойте номер строки 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
  • 0
    Не получается получить правильные данные при использовании sqlfiddle.com/#!9/658272, хотя пример базы данных может быть неполным, так как я раньше не пользовался сайтом, поэтому, возможно, потребуется немного доработать, спасибо.
  • 0
    @HeadbangA Ваши тестовые данные в sqlfiddle действительно неполны. Много предложений без записи в таблице запасов.
Показать ещё 1 комментарий

Ещё вопросы

Сообщество Overcoder
Наверх
Меню