【问题标题】:Prevent Multiple Entry in Table防止表中的多个条目
【发布时间】:2018-07-16 05:21:00
【问题描述】:

我很困惑,在获得如下图所示的输出时遇到了问题 所需输出

我有一个名为 number_status 的数据库表,我在其中存储带有时间戳的数字在线和离线历史记录。我需要在我的 android 应用程序中获取显示数据的 json 响应,如上图。我可以像下面的函数一样得到它

  public function compareNumber($firstNumber, $secondNumber, $email, $date) {
        $response = array('code' => 0, 'error' => false);
        $endDate = date('Y-m-d', strtotime("+1 day", strtotime($date))) . " " . explode(" ", $date)[1];

        $stmt = $this->conn->prepare("SELECT id FROM user WHERE email = ?");
        $stmt->bind_param("s", $email);
        $stmt->execute();
        $result = $stmt->get_result();
        if ($result->num_rows) {
            $user =  $result->fetch_assoc();            
            $user_id = $user['id'];
            $stmt->close();

            $response["received"]   = $date;
            $response["created_at"] = $date;
            $response["end"]        = $endDate;
            $response["code"]       = 1;

            $arr = $this->helperNumber($firstNumber, $date, $endDate, $user_id);
            $arr1 = $this->helperNumber($secondNumber, $date, $endDate, $user_id);

            $response["logs"] = array_merge($arr, $arr1);
        }

        return $response;
    }

    public function helperNumber($numberToSearch, $date, $endDate, $user_id) {
        $stmt = $this->conn->prepare("SELECT number, number_status, status_time FROM number_status WHERE number = ? AND  user_id=? AND status_time > ? AND status_time < ? ORDER BY status_time DESC");
            $stmt->bind_param("iiss", $numberToSearch, $user_id, $date, $endDate);
            $stmt->execute();
            $result = $stmt->get_result();

            $number = array();
            if ($result->num_rows) {
                $lastrow = null;
                $i = 0;
                while($row = $result->fetch_assoc()) {
                    if(!isset($number[$i]))
                        $number[$i] = array('number' => $row['number'], 'start_time' => false, 'end_time' => false);

                    if($lastrow == null){
                        // take offline as first entry
                        if($row['number_status'] == 0) {
                            $number[$i]['end_time'] = $row['status_time'];
                        }
                    } else {
                        // if two repeated entry for online/offline skip it
                        if($lastrow['number_status'] == 0 && $row['number_status'] == 0) 
                            continue;
                        if($lastrow['number_status'] == 1 && $row['number_status'] == 1)
                            continue;

                        if($row['number_status'] == 1){
                            $number[$i]['start_time'] = $row['status_time'];
                        }
                        else  {
                            $number[$i]['end_time'] = $row['status_time'];  
                        }
                        if($number[$i]['start_time'] && $number[$i]['end_time'])
                            $i++;

                    }

                    $lastrow = $row;

                }

            }
            $stmt->close();
            return $number;
    }

我正在收到上述函数的 json 响应,如下所示

{"code":1,"error":false,"received":"2018-07-15 00:00:00","created_at":"2018-07-15 00:00:00","end":"2018-07-16 00:00:00","logs":[{"number":"919400000001","start_time":"2018-07-15 16:11:04","end_time":"2018-07-15 16:12:03"},{"number":"919400000001","start_time":"2018-07-15 10:35:47","end_time":"2018-07-15 10:37:34"},{"number":"919400000001","start_time":"2018-07-15 10:31:03","end_time":"2018-07-15 10:33:43"},{"number":"919400000001","start_time":"2018-07-15 10:27:28","end_time":"2018-07-15 10:27:46"},{"number":"919400000001","start_time":"2018-07-15 10:26:55","end_time":"2018-07-15 10:27:26"},{"number":"919400000001","start_time":"2018-07-15 10:25:38","end_time":"2018-07-15 10:25:50"},{"number":"919400000001","start_time":"2018-07-15 10:24:51","end_time":"2018-07-15 10:25:14"},{"number":"919400000000","start_time":"2018-07-15 10:55:18","end_time":"2018-07-15 16:11:04"},{"number":"919400000000","start_time":"2018-07-15 10:33:50","end_time":"2018-07-15 10:34:04"},{"number":"919400000000","start_time":"2018-07-15 10:27:20","end_time":"2018-07-15 10:27:38"},{"number":"919400000000","start_time":"2018-07-15 10:25:42","end_time":"2018-07-15 10:25:57"},{"number":"919400000000","start_time":"2018-07-15 10:24:57","end_time":"2018-07-15 10:25:22"}]}

但我想按结束时间排序(离线)。我不知道我该怎么做。在我的数据库表中有单独的在线(开始时间)和离线(结束时间)条目。让我知道是否有人可以帮助我获得它。 谢谢

【问题讨论】:

    标签: php mysql sql mysqli


    【解决方案1】:

    以下内容可能会满足您的需求 - 但会涉及对您的 PHP 代码的一些更改。

    select number, min(start_time), end_time 
    from (
      select t1.number as number, 
             t2.status_time as start_time, 
             min(t1.status_time) as end_time 
      from number_status t1 
        inner join number_status t2
          on 
              t1.number=t2.number and 
              t1.number_status=0 and 
              t2.number_status=1 and 
              t1.status_time > t2.status_time and
              t1.user_id=t2.user_id
      where 
         (t1.number=? or t1.number=?) AND 
         t1.user_id=? AND 
         t2.status_time > ? AND t1.status_time < ?
      group by t1.number, t2.status_time ) t
    GROUP BY number, end_time
    ORDER BY end_time DESC;
    

    查询的工作方式如下: 首先,number_status 表与自身的内部连接创建了一个包含 number、start_time 和 end_time 的条目列表(t1 标签代表 end_time,t2 标签代表 start_time)。使用连接条件,这将包括从 t2 开始的每个可能的 start_time 以及从 t1 开始的大于 start_time 的每个可能的 end_time。

    where 部分限制了数字、user_id 和 status_time 值的集合。 group by (t1.number, t2.status_time) 和 select 中的 min(t1.status_time) 只留下那些具有相同 start_time 和相同编号以及可能的最小 end_time 的记录。

    周边选择有两个目标: 首先,为每个 end_time 选择可用的最小 start_time(同样是 group by 和 min); 其次,按 end_time 排序结果(在这种情况下,我选择了 DESC - 但 ASC 也是可能的)。

    我确信同样可以直接在 PHP 中很容易地完成,但我不知道如何......

    【讨论】:

    • 请解释这个纯代码答案。发布答案时,请始终努力进行教育。发布正确的解决方案只是“好”答案的开始。
    猜你喜欢
    • 2011-07-04
    • 2014-10-12
    • 2011-12-27
    • 2016-12-12
    • 1970-01-01
    • 2018-07-14
    • 2014-09-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多