В SQL Server это было бы легко осуществить с помощью функции ROW_NUMBER()
или конструкции CROSS APPLY
. В MySQL это сложнее .
Одним из решений является эмулировать ROW_NUMBER () в MySQL с использованием переменных. Таким образом, можно вернуть ставки для каждого идентификатора поста, ранжированного по времени ставки, и получить user_ids. С этого момента легко присоединиться к времени SMS к комбинации post_id / user_id. Следуя примеру в ссылке, код будет выглядеть примерно так:
SELECT tmp.Post_ID, tmp.ranking, tmp.user_ID, tmp.Bid_DT, s.SMS_DT
FROM (
SELECT
b.Post_ID, b.user_ID, b.Bid_DT,
IF( @prev <> ID, @rownum := 1, @rownum := @rownum+1 ) AS ranking,
@prev := ID
FROM tbl_bids b
JOIN (SELECT @rownum := NULL, @prev := 0) AS r
ORDER BY b.Post_ID, b.BID_DT
) AS tmp
LEFT JOIN tbl_sms s
ON tmp.Post_ID = s.Post_ID AND tmp.user_ID = s.user_ID
WHERE tmp.rank <= 3 -- Top 3, adjust when more are necessary
ORDER BY post_ID, ranking;
Затем у вас будет такой вывод:
Post_ID | Ranking | User_ID | Bid_DT | SMS_DT
---------------------------------------------------------------------------
123 | 1 | 010 | 2010-05-14 10:27:25 | 2010-05-14 10:23:06
123 | 2 | 008 | 2010-05-14 10:28:32 | ....
123 | 3 | 009 | 2010-05-14 10:28:47 | ....
123 | 4 | 007 | 2010-05-14 10:35:06 | ....
124 | 1 | .......
Вы можете сохранить этот результат во временной таблице:
CREATE TEMPORARY TABLE RankedBids(Post_ID INTEGER, Ranking INTEGER, User_ID INTEGER, Bid_DT DATETIME, SMS_DT DATETIME)
INSERT INTO Rankedbids SELECT.... (use above query)
К сожалению, из-за ограничения MySQL вы не можете использовать несколько ссылок на одну и ту же временную таблицу в запросе, поэтому вам придется разделить эту таблицу по рангу:
CREATE TEMPORARY TABLE RankedBids1(Post_ID INTEGER, User_ID INTEGER, Bid_DT DATETIME, SMS_DT DATETIME)
CREATE TEMPORARY TABLE RankedBids2....
INSERT INTO Rankedbids1 SELECT Post_ID, User_ID, Bid_DT, SMS_DT FROM RankedBids WHERE Ranking = 1
INSERT INTO RankedBids2...
Если набор записей очень велик, полезно назначить индекс (первичный ключ) для Post_ID, чтобы ускорить поворотный запрос.
Теперь вы можете изменить эти данные:
SELECT R1.Post_ID, R1.Bid_DT AS Bid_DT1, R1.SMS_DT AS SMS_DT1 ....
FROM RankedBids1 R1
LEFT JOIN RankedBids2 R2 ON R1.Post_ID = R2.Post_ID
LEFT JOIN RankedBids3 R3 ON ........
У OMG Ponies есть смысл, однако, более масштабируемо построить свою систему за неповоротным столом. Так что, если вам не нужно поворачиваться, не надо.