具有不同键值的唯一多维数组值

时间:2014-11-27 16:11:55

标签: php mysql arrays multidimensional-array

我有一个MySQL表,我将所有网站页面加载存储在这样的内容中:
[IP] [日期] [主机名]

主要查询类似于

$log = mysqli_query($con, "SELECT * FROM log");

然后我把所有的值都放到一个数组中:

while ($result = mysqli_fetch_assoc($log)) {
  $log_array[] = $result;
}

所以现在我有一个名为$ log_array的PHP数组,带有aprox。 20K行。 显然有重复的IP条目 例如:

Array
(
    [0] => Array
        (
            [ip] => 12.34.56.78
            [date] => 2014-11-25 22:03:01
            [host] => fakehost1
        )

    [1] => Array
        (
            [ip] => 12.34.56.78
            [date] => 2014-11-25 22:03:01
            [host] => fakehost1
        )

    [2] => Array
        (
            [ip] => 98.76.54.32
            [date] => 2014-11-25 22:03:03
            [host] => fakehost2
        )

    [3] => Array
        (
            [ip] => 12.34.56.78
            [date] => 2014-11-25 22:03:05
            [host] => fakehost3
        )

    [4] => Array
        (
            [ip] => 98.76.54.32
            [date] => 2014-11-25 22:03:06
            [host] => fakehost2
        )
)

我想获得一个具有唯一IP地址和最后日期和最后一个主机的数组,并且还要计算重复的IP,所以我想获得这样的内容:

Array
(
    [0] => Array
        (
            [ip] => 12.34.56.78
            [times] => 3
            [lastdate] => 2014-11-25 22:03:05
            [lasthost] => fakehost3
        )

    [1] => Array
        (
            [ip] => 98.76.54.32
            [times] => 2
            [lastdate] => 2014-11-25 22:03:06
            [lasthost] => fakehost2
        )
)

我一直试图解决这个问题几个星期到处阅读并学习php数组功能,但我看不出怎么做。
提前谢谢!

4 个答案:

答案 0 :(得分:0)

您可以使用子查询。例如:

SELECT l.ip, COUNT(SELECT * FROM log l2 WHERE l.ip = l2.ip) as times FROM log GROUP BY ip

显然,你需要用你的其他值来扩展它。

答案 1 :(得分:0)

这应该有效:

$log = mysqli_query($con, "SELECT ip,date,host,count(*) as tot FROM log GROUP by ip ");

答案 2 :(得分:0)

使用PHP

您使用foreach。例如:https://eval.in/227238

$arrFinal = array();
foreach($a as $record) {
   if( array_key_exists($record['ip'], $arrFinal) ) {
     //Update
     $arrFinal[$record['ip']]['times'] += 1; //+1 to the time
     if( strtotime($record['date']) > strtotime($arrFinal[$record['ip']]['lastdate']) ) {
         //This is a newer record
         $arrFinal[$record['ip']]['lastdate'] = $record['date']; //Update last date
         $arrFinal[$record['ip']]['lasthost'] = $record['host']; //Update last host
     }
   } else {
      //New entry
      $arrFinal[$record['ip']] = array(
        'ip' => $record['ip'],
        'times' => 1,
        'lastdate' => $record['date'],
        'lasthost' => $record['host']
      );
   }
}  

使用MySQL

select l1.ip,
       count(l1.`ip`) as times,
       max(l1.`date`) as lasttime,
       (select l2.`host` as lasthost 
        from log l2
        where l2.ip = l1.ip
        order by `date` desc 
        limit 1) as lasthost
from log l1
group by l1.`ip`

使用相同的dummy results in the PHP example,我们会得到以下结果集;

+-----------+-------+---------------------+-----------+
| ip        | times | lasttime            | lasthost  |
+-----------+-------+---------------------+-----------+
| 127.0.0.1 |     3 | 2014-11-25 22:03:01 | localhost |
| 88.88.88  |     2 | 2014-11-25 22:03:01 | google    |
+-----------+-------+---------------------+-----------+
2 rows in set

答案 3 :(得分:-1)

尝试使用SELECT DISTINCT声明。

$log = mysqli_query($con, "SELECT DISTINCT ip, times, lastdate, lasthost FROM log");