按共同值对值进行分组:userid和ipaddress

时间:2014-12-23 12:05:22

标签: php

我正在处理数据库中的问题。我正在尝试查找使用多个帐户的用户。 我有一个用户ID和使用的IP地址列表,如下所示:

用户ID // IP地址

  • 1 // IP地址13
  • 2 // IP地址23
  • 1 // IP地址12
  • 4 // IP地址56
  • 9 // IP地址23
  • 5 // IP地址12
  • 2 // IP地址56

我想像这样分组。具有用户标识1的用户使用地址13和12,具有标识5的用户也使用IP地址12,因此它们可能由同一个人使用......依此类推。

最后我需要这样的团体(如果我没有弄错的话):

第1组:

用户ID 1,IP地址13,IP地址12,用户ID 5

第2组:

用户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;
    }

这里我循环云中的值并检查另一个云是否包含该值。如果是这样,我删除当前的值并将所有其他值存储到匹配的云中。之后循环将停止并开始另一次检查。这种情况一次又一次地发生,直到找不到更多的匹配。

你怎么看?!有更好的方式吗?我想我创造了一个怪物。但我可以找到更好的解决方案。

3 个答案:

答案 0 :(得分:1)

使用GROUP_CONCAT()

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     |
+---------+---------+