2016-09-19 48 views
-2

我想在我们的数据库用户之间创建随机的用户对。从表中随机选择唯一的用户对

我有以下的用户表:

表:tbl_users

user_id | name 
--------+-------------- 
1  | Jay 
2  | Ram 
3  | John 
4  | Kevin 
5  | Jenny 
6  | Tony 

我要生成一个随机的结果是这样的:

from_id | to_id 
--------+--------- 
1  | 6 
5  | 3 
2  | 4 

可以这样在MySQL做只要?

+0

可能的复制http://stackoverflow.com/questions/4823208/how-do-i-select-unique-pairs-of-rows-from-a-随机表 – Jagrati

+0

由于您用'php'标记了它:在php中这样做。在mysql中这将是低效的。用数字1 ... max生成一个数组,使用例如[洗牌](http://php.net/manual/de/function.shuffle。php)并使用该数组填充配对表(数组中的第1个值是第1个'from_id',第2个值是第1个'to_id',第3个值是第2个'from_id'等等)。 – Solarflare

+0

感谢@Solarflare的评论,但我想随机用户配对来自数据库的记录。随机配对很容易在PHP中设置,但我想从数据库选择查询。 –

回答

0

这确实是a previous question的重复,所以答案就在那里。

但是,即使在MySQL中确实有可能这样做,也没有真正推荐。 PHP是一个更好的工具来处理这个问题,因为你所做的实际上是根据一些业务规则操纵数据。通过在PHP中进行维护会更容易,我怀疑它的资源密集程度也会降低。

一个可能的方法来做到这一点,我更喜欢。是在SQL中进行随机排序,然后将两行和两行相互配对。类似这样的:

$grouping = {}; 
// Fetching both rows to ensure that we actually have an even number paired up. 
while ($row = $res->fetch_array() && $row2 = $res->fetch_array()) { 
    $grouping[] = {$row['name'], $row2['name']}; 
} 

如果您想允许列出不匹配的用户,只需将第二个提取移到循环的内部即可。然后处理那里可能遗漏的结果。

0

您可以使用下面的代码来生成列表:

select max(from_id) as from_id, 
     max(to_id) as to_id 
from (
    select 
    case when rownum mod 2 = 1 then user_id else null end as from_id, 
    case when rownum mod 2 = 0 then user_id else null end as to_id, 
    (rownum - 1) div 2 as pairnum 
    from (
    select user_id, @rownum := @rownum + 1 as rownum 
    from 
     (select @rownum := 0) as init, 
     (select user_id from tbl_user order by rand()) as randlist 
) as randlistrownum 
) as randlistpairs 
group by pairnum; 

一步一步来,这样会:

  • 顺序按随机顺序
  • 的用户列表分配ROWNUMBER到它(否则命令将没有意义)
  • 分配两个连续的行相同pairnumrownum = 1rownum = 2得到值pairnum = 0,接下来的两行获得pairnum = 1等)
  • 这些成对的行中的第一行会得到一个值from_id = user_idto_id = null,另一列将是to_id = user_idfrom_id = null
  • group by这些对在一起,使它们变成一排
  • ,如果你有一个奇数数量的用户,一个用户将最终to_id = null,因为它没有伙伴

锂如果你喜欢短代码ttle更紧凑:中

select max(case when rownum mod 2 = 1 then user_id else null end) as from_id, 
     max(case when rownum mod 2 = 0 then user_id else null end) as to_id 
from (
    select user_id, @rownum := @rownum + 1 as rownum, (@rownum - 1) div 2 as pairnum 
    from 
    (select @rownum := 0) as init, 
    (select user_id from tbl_user order by rand()) as randlist 
) as randlistpairs 
group by pairnum;