我正在处理数据库中的问题。我正在尝试查找使用多个帐户的用户。 我有一个用户ID和使用的IP地址列表,如下所示:
我想像这样分组。具有用户标识1的用户使用地址13和12,具有标识5的用户也使用IP地址12,因此它们可能由同一个人使用......依此类推。
最后我需要这样的团体(如果我没有弄错的话):
用户ID 1,IP地址13,IP地址12,用户ID 5
用户ID 2,IP地址23,用户ID 9,用户ID 4,IP地址56
请帮助我,我不会对此感到满意! 我怎样才能以一种很好的方式解决这个问题?
这是我的解决方案。实际上我认为我已经创建了一个代码Moster。所以,如果有人能找到更好的解决方案,我会非常感激;)
首先,生病需要这个功能来检查一个值是否在多维数组中:
function in_array_r($needle, $haystack, $strict = false) {
foreach ($haystack as $key => $item) {
if (($strict ? $item === $needle : $item == $needle) || (is_array($item) && in_array_r($needle, $item, $strict))) {
return $key;
}
}
return false;
}
以下数组包含IP地址和用户ID:
$userids_using_same_ip[$ipadresss] = array("$userid1,$userid2 ....);
我将稍后在一个名为$ sameuserandidcloud
的数组中对使用不同帐户或Ipaddresses发布的人进行分组这是我的代码,首先我将阅读$ userids_using_same_ip数组:
$cloundnr=0;
$sameuserandidcloud = array();
foreach($userids_using_same_ip as $ip => $userids) {
foreach($userids_using_same_ip[$ip] as $userid) {
// In this loop i have the $ip and the $userid and im going to store them in the $sameuserandidcloud array
$checkip = in_array_r($ip, $sameuserandidcloud);
$checkuserid = in_array_r($userid, $sameuserandidcloud);
if($checkip==false && $checkuserid==false) {
//Create new Cloud
$cloundnr++;
if(!is_array($sameuserandidcloud[$cloundnr])) $sameuserandidcloud[$cloundnr] = array();
array_push($sameuserandidcloud[$cloundnr],$ip,$userid);
}
else {
if($checkip != false) array_push($sameuserandidcloud[$checkip],$ip,$userid);
elseif($checkuserid != false) array_push($sameuserandidcloud[$checkuserid],$ip,$userid);
}
}
}
现在我有一个包含$ ip和$ userids的数组。但尚未完成。因为我在一个循环中创建了这个数组,所以可能存在已经存储到云中的ips和id,之后会添加其他可能的匹配值。所以我需要再次循环整个数组。
while($loop!=1) {
$break=0;
$loop=1;
foreach($sameuserandidcloud as $cloudid => $idanduseridarray) {
$break=0;
foreach($sameuserandidcloud[$cloudid] as $ipOrUserid) {
$check = in_array_r($ipOrUserid, $sameuserandidcloud);
if($check != false && $check != $cloudid) {
array_push($sameuserandidcloud[$check],$sameuserandidcloud[$cloudid][0]);
unset($sameuserandidcloud[$cloudid]);
$break = 1;
$loop = 0;
break;
}
}
if($break==1) break;
}
echo $break;
}
这里我循环云中的值并检查另一个云是否包含该值。如果是这样,我删除当前的值并将所有其他值存储到匹配的云中。之后循环将停止并开始另一次检查。这种情况一次又一次地发生,直到找不到更多的匹配。
你怎么看?!有更好的方式吗?我想我创造了一个怪物。但我可以找到更好的解决方案。
答案 0 :(得分:1)
SELECT user_id, GROUP_CONCAT(DISTINCT ip_address SEPARATOR ', ')
FROM TABLE_NAME GROUP BY user_id
答案 1 :(得分:1)
这是我的解决方案。实际上,我认为我已经创建了一个代码怪物。因此,如果有人能找到更好的解决方案,我会非常适合它。
首先,不需要这个函数来检查一个值是否在多维数组中:
function in_array_r($needle, $haystack, $strict = false) {
foreach ($haystack as $key => $item) {
if (($strict ? $item === $needle : $item == $needle) || (is_array($item) && in_array_r($needle, $item, $strict))) {
return $key;
}
}
return false;
}
以下数组包含IP地址和用户ID:
$userids_using_same_ip[$ipadresss] = array("$userid1,$userid2 ....);
我将稍后在一个名为$ sameuserandidcloud
的数组中对使用不同帐户或Ipaddresses发布的人进行分组这是我的代码,首先我将阅读$ userids_using_same_ip数组:
$cloundnr=0;
$sameuserandidcloud = array();
foreach($userids_using_same_ip as $ip => $userids) {
foreach($userids_using_same_ip[$ip] as $userid) {
// In this loop i have the $ip and the $userid and im going to store them in the $sameuserandidcloud array
$checkip = in_array_r($ip, $sameuserandidcloud);
$checkuserid = in_array_r($userid, $sameuserandidcloud);
if($checkip==false && $checkuserid==false) {
//Create new Cloud
$cloundnr++;
if(!is_array($sameuserandidcloud[$cloundnr])) $sameuserandidcloud[$cloundnr] = array();
array_push($sameuserandidcloud[$cloundnr],$ip,$userid);
}
else {
if($checkip != false) array_push($sameuserandidcloud[$checkip],$ip,$userid);
elseif($checkuserid != false) array_push($sameuserandidcloud[$checkuserid],$ip,$userid);
}
}
}
现在我有一个包含$ ip和$ userids的数组。但尚未完成。因为我在一个循环中创建了这个数组,所以可能有ips和id已经存储到云中,然后才会添加其他可能的匹配值。所以我需要再次循环整个数组。
while($loop!=1) {
$break=0;
$loop=1;
foreach($sameuserandidcloud as $cloudid => $idanduseridarray) {
$break=0;
foreach($sameuserandidcloud[$cloudid] as $ipOrUserid) {
$check = in_array_r($ipOrUserid, $sameuserandidcloud);
if($check != false && $check != $cloudid) {
array_push($sameuserandidcloud[$check],$sameuserandidcloud[$cloudid][0]);
unset($sameuserandidcloud[$cloudid]);
$break = 1;
$loop = 0;
break;
}
}
if($break==1) break;
}
echo $break;
}
这里我循环云中的值并检查另一个云是否包含该值。如果我删除当前的值并将所有其他值存储到匹配的云中。之后循环将停止并开始另一次检查。这种情况一次又一次地发生,直到找不到更多的匹配。
你怎么看?有更好的方法吗?我想我创造了一个丑陋的怪物。但我能找到更好的解决方案答案 2 :(得分:0)
从您的示例中获取数据:
+--------+---------+
| userid | address |
+--------+---------+
| 1 | 12 |
| 5 | 12 |
| 1 | 13 |
| 2 | 23 |
| 9 | 23 |
| 2 | 56 |
| 4 | 56 |
+--------+---------+
表格定义为
CREATE TABLE table_27620030 (
userid INTEGER,
address INTEGER
);
以下查询将列出共享相同地址(和地址)的所有用户ID:
SELECT address, GROUP_CONCAT(userid) userids
FROM table_27620030
GROUP BY address
HAVING COUNT(DISTINCT userid) > 1
ORDER BY address
;
结果:
+---------+---------+
| address | userids |
+---------+---------+
| 12 | 1,5 |
| 23 | 2,9 |
| 56 | 2,4 |
+---------+---------+