我很困惑,在获取下图所示的输出时遇到了问题 必需的输出
我有一个名为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"}]}
但是我想按结束时间(离线)进行排序。我不知道该怎么做。在我的数据库表中,在线(开始时间)和离线(结束时间)有单独的条目。让我知道是否有人可以帮助我。 谢谢
答案 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中也可以很容易地完成同样的事情,但是我对如何...感到茫然。