【问题标题】:Unique multidimensional arrays values with different key values具有不同键值的唯一多维数组值
【发布时间】:2014-11-27 16:11:55
【问题描述】:

我有一个 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 数组函数,但我不知道该怎么做。
提前致谢!

【问题讨论】:

  • 表中是否也有记录ID?还是只有这 3 个字段?
  • 我还有一个自动递增的“id”字段。

标签: php mysql arrays multidimensional-array


【解决方案1】:

使用 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
    

【讨论】:

  • OP 说他们有aprox. 20K rows。这个 php 解决方案需要将所有这些行从 mysql 带回 PHP 并循环它们。 mysql 结果显示 2014-11-23 作为本地主机的最后日期,而您的小提琴也有 11-25。这是 localhost 的最后日期
  • 对查询所做的更改 :) 我也提供了 PHP 答案,因为 PHP 被标记了
  • 查询似乎有效,但处理需要 24 秒。太慢了。
  • 我现在做到了。它就像一个魅力。 0.1 秒。这是正确答案。谢谢!
【解决方案2】:

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

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

显然,您需要通过其他值来扩展它。

【讨论】:

    【解决方案3】:

    这应该可行:

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

    【讨论】:

    • 这就是我要找的,我不知道“GROUP BY”可以做到这一点。但是,在结果中你没有得到最后一个主机或最后一个日期。查询应该从每个组中选择最后一项。好消息是这个查询只需要 0.07 秒来处理。如果我找到它,我会发布解决方案。
    • 在组语句中添加ORDER BY,如果您想要最后一项,请使用ORDER BY ip,date,host GROUP by ip,date,host
    【解决方案4】:

    尝试使用SELECT DISTINCT 语句。

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-08-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多