Получение случайной записи из базы данных с помощью группы - PullRequest
1 голос
/ 16 марта 2010

Здравствуйте, у меня есть вопрос по выбору случайных записей из базы данных. У меня есть 4 таблицы, продукты, предложения и ставки, а также пользователи.

Products
-------  
id 20,21,22,23,24(prime_key)
price...........
etc...........

users  
-------
id(prim_key)  
name user1,user2,user3  
etc  

bids  
-------
product_id  
user_id  
created  

autobids  
--------
user_id   
product_id 

Теперь у нескольких пользователей может быть автобид на продукт. Таким образом, для следующего участника торгов я хочу выбрать случайного пользователя из таблицы autobid

пример запроса на языке:

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

На товар 20 есть пользовательские торги user1, user2, user3.
На товар 21 есть пользователь1, пользователь2, пользователь3 автобид

Тогда я хочу получить набор результатов, который выглядит, например, следующим образом

20 - пользователь2
21 - пользователь3

Просто случайный пользователь. Я попытался смешать GOUP BY (product_id) и сделать его RAND (), но я просто не могу получить правильные значения из него. Теперь я получаю случайного пользователя, но все соответствующие ему значения не совпадают.

Может кто-нибудь, пожалуйста, помогите мне построить этот запрос, я использую php и mysql

Ответы [ 2 ]

1 голос
/ 17 марта 2010

Первая часть решения связана с определением последней ставки для каждого продукта: они в конечном итоге попадают во временную таблицу «latest_bid».

Затем мы присваиваем ранговые значения рангов каждому автобиду для каждого продукта - исключая последнюю ставку для каждого продукта. Затем мы выбираем самое высокое значение ранга для каждого продукта, а затем выводим user_id и product_id автобид с этими самыми высокими значениями ранга.

create temporary table lastbids (product_id int not null, 
                                 created datetime not null, 
                                 primary key( product_id, created ) );

insert into lastbids 
select product_id, max(created)
from bids
group by product_id;

create temporary table latest_bid ( user_id int not null, 
                                    product_id int not null, 
                                    primary key( user_id, product_id) );

insert into latest_bid
select product_id, user_id 
from bids b
join lastbids lb on lb.product_id = b.product_id and lb.created = b.created;

create temporary table rank ( user_id int not null, 
                              product_id int not null, 
                              rank float not null, 
                              primary key( product_id, rank ));

# "ignore" duplicates - it should not matter
# left join on latest_bid to exclude latest_bid for each product

insert ignore into rank 
select user_id, product_id, rand() 
from autobids a
left join latest_bid lb on a.user_id = lb.user_id and a.product_id = lb.product_id 
where lb.user_id is null;

create temporary table choice 
as select product_id,max(rank) choice 
   from rank group by product_id;

select user_id, res.product_id from rank res
join choice on res.product_id = choice.product_id and res.rank = choice.choice;
1 голос
/ 16 марта 2010

Вы можете использовать оператор LIMIT вместе с серверной ПОДГОТОВКОЙ.

Вот пример, который выбирает случайную строку из таблицы mysql.help_category:

select @choice:= (rand() * count(*)) from mysql.help_category;
prepare rand_msg from 'select * from mysql.help_category limit ?,1';
execute rand_msg using @choice;
deallocate prepare rand_msg;

Это потребует уточнения, чтобы @choice не стал равным нулю, но общая идея работает.

В качестве альтернативы ваше приложение может создать сам счет, выполнив первый выбор и создав второй выбор с жестко заданным предельным значением:

select count(*) from mysql.help_category;
# application then calculates limit value and constructs the select statement:   
select * from mysql.help_category limit 5,1;
...