我想在我们的数据库用户之间创建随机用户对。
我有如下的用户表:
表: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中完成吗?
这确实是前一个问题的重复,所以答案在那里。
然而,即使在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']};
}
如果要允许列出不匹配的用户,只需将第二次取操作移到循环内部即可。然后处理那里可能缺少的结果。
您可以使用以下代码来生成列表:
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;
一步一步,这将:
- 将用户列表按随机顺序排序
- 为其分配行号(否则该顺序将没有意义)
- 将相同的
pairnum
分配给连续的两行(rownum = 1
和rownum = 2
获得pairnum = 0
的值,接下来的两行将获得pairnum = 1
,以此类推) - 这些配对行的第一行将获得
from_id = user_id
和to_id = null
的值,另一行将是to_id = user_id
和from_id = null
-
group by
将这些对放在一起使它们成为一行 - 如果你有一个奇数的用户,一个用户将结束与
to_id = null
,因为它没有伙伴
如果您喜欢更短的代码,则更紧凑:
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;