2014-01-29 3 views
0

У меня есть сайт, на котором пользователи могут перечислить элементы для продажи. На передней панели сайта отображаются случайные элементы в продаже с использованием следующего SQL.Ограниченное количество результатов MySQL на пользователя

SELECT * FROM auctions 
WHERE closed = 0 AND suspended = 0 AND starts <= 1390990443 
ORDER BY RAND() LIMIT 30 

Проблема в том, что у одного пользователя есть много продаж в той мере, в которой перед сайтом в основном используется один пользователь. Я хотел бы ограничить элементы, отображаемые пользователем, используя столбец auction.user для пяти элементов на пользователя.

Я надеюсь, что SQL будет делать это в одной строке, если нет, то совет или ссылка на то, кто будет создавать результаты по нескольким запросам, будут оценены. Кодированный язык - это PHP.

Редактировать: структура базы данных находится здесь. http://pastebin.com/3ua18k4h

+1

вы можете работать над sql для каждого пользователя и добавить ограничение 5 –

+0

@SatishSharma - о, да, это отличный план! (не) – Strawberry

+0

6 запросов для решения одной проблемы? Вероятно, есть более умный способ. – MLeFevre

ответ

2

Лично я хотел бы попробовать и сформировать некоторые решение вытягивает результаты в PHP и фильтрует их там, но это потому, что я чувствую себя более комфортно в PHP, чем MySQL. Однако вы могли бы сделать что-то вроде этого без фильтрации PHP и просто с помощью запроса MySQL, не знаю, как это будет делать масштабирование до большого количества пользователей, хотя (не уверен в вашей полной схеме таблицы, так что я импровизировал)

SELECT ID, USERNAME, AUCTION_ID 
FROM 
(
    SELECT *, @row:=IF([email protected],@row,0)+1 AS auctioncount, @username:=username FROM 
    (SELECT *,RAND() AS trand FROM table1) t1, 
    (SELECT @row:=0,@username:='') tm2 
    ORDER BY username,trand 
) t2 
WHERE auctioncount<=5 LIMIT 30 

SQL скрипт: http://sqlfiddle.com/#!2/9bd47/1

Вы можете изменить auctioncount на максимальное количество списков, которое нужно пользователю.

+0

Это отлично, спасибо за код. Теперь я живу на этом сайте, и это именно то, что мне нужно. –

+0

@ Bushstar просто из интереса (если вы можете узнать), как долго этот запрос берет ваш набор данных из ~ 1500 строк? – MLeFevre

+0

Запустив это с помощью профилировщика, я вижу, что продолжительность составляет 0,34166050, что, я полагаю, составляет секунды. –

1

Вы можете получить больше результатов с помощью MYSQL с большим LIMIT, а затем создать массив для каждого элемента для продажи пользователем и, наконец, взять только 5 элементов на пользователя, так что вы будете использовать только 1 запрос для Mysql и больше использования ЦП , может быть хорошей идеей, если у вас много трафика на вашем веб-сайте.

1) получить больше результатов:

SELECT * FROM auctions 
WHERE closed = 0 AND suspended = 0 AND starts <= 1390990443 
ORDER BY RAND() LIMIT 1000 

2) Loop и магазин за предметы для каждого пользователя:

foreach($results as $item) { 
    array_push($itemsPerUser[$item['userId']], $item); 
} 

3) фильтра только 5 элементов на пользователя:

foreach($itemsPerUser as $user => $items) { 
    $fiveItemsPerUser = array_slice($items, 0, 5); 
} 

PS: это псевдокод, вы должны добавить дополнительную проверку длины массива и т. Д.

0

Вот о чем подумать, хотя я понимаю, что интеллектуальный скачок от этого к (справедливой и) рабочего раствора может быть слишком далеко! ...

SELECT RAND(@i:=RAND()*1000); 
+-----------------------+ 
| RAND(@i:=RAND()*1000) | 
+-----------------------+ 
| 0.7903550134881911 | 
+-----------------------+ 

SELECT RAND(@i); 
+--------------------+ 
| RAND(@i)   | 
+--------------------+ 
| 0.7903550134881911 | 
+--------------------+ 

SELECT RAND(@i:=RAND()*1000); 
+-----------------------+ 
| RAND(@i:=RAND()*1000) | 
+-----------------------+ 
| 0.9555754568014065 | 
+-----------------------+ 
1

Не совсем прямой ответ на вашу проблему, но, возможно, следующее достаточно:

Выбор 30 случайных пользователей с работы аукционов, а также отображать старейшая аукцион каждого из них:

SELECT * FROM auctions WHERE id IN (
    SELECT MIN(id) FROM auctions 
    WHERE closed = 0 AND suspended = 0 AND starts <= 1390990443 
    GROUP BY userid ORDER BY RAND() LIMIT 30 
) 

По крайней мере, вы можете удалить новые строки и все это выполнить в одном запросе sql-строки, который не может быть выполнен с запрошенным вами запросом.

+0

Спасибо, это интересный вариант. –

Смежные вопросы