防止在表中多次输入

时间:2018-07-16 05:21:01

标签: php mysql sql mysqli

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

Required Output

我有一个名为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"}]}

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

1 个答案:

答案 0 :(得分:-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表的内部联接与其自身一起创建一个具有数字,start_time和end_time的条目列表(t1标签为end_time,t2标签为start_time)。根据加入条件,这将包括从t2开始的每个可能的start_time和从t1开始的每个可能的end_time(大于start_time)。

where部分限制数字集,user_id和status_time值。 选择中的min(t1.status_time)与(t1.number,t2.status_time)分组,仅保留那些具有相同start_time,相同数字和最小可能end_time的记录。

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

我敢肯定,直接在PHP中也可以很容易地完成同样的事情,但是我对如何...感到茫然。