我对PHP编程相对较新,所以如果这是一个相当简单的问题我会道歉。
我有一个名为MachineReports的MySQL数据库表,其中包含以下值:ReportNum(主键,自动增量),MachineID和Timestamp
以下是一些示例数据:
|ReportNum | MachineID | Timestamp |
|1 | AD3203 | 2012-11-18 06:32:28|
|2 | AD3203 | 2012-11-19 04:00:15|
|3 | BC4300 | 2012-11-19 04:00:15|
我试图通过迭代每个行集找到每个机器ID的时间戳差异(以秒为单位)。但是,我正在坚持最好的方法。这是我到目前为止编写的代码:
<?php
include '../dbconnect/dbconnect.php';
$machineID=[];
//Get a list of all MachineIDs in the database
foreach($dbh->query('SELECT DISTINCT(MachineID) FROM MachineReports') as $row) {
array_push($machineID, $row[0]);
}
for($i=0;$i<count($machineID);$i++){
foreach($dbh->query("SELECT MachineID FROM MachineReports WHERE MachineID='$machineID[$i]' ORDER BY MachineID") as $row) {
//code to associate each machineID with two time stamps goes here
}
}
&GT?; 此代码只是逐行列出表的内容。 我的最终目标是找到某个MachineID的时间戳差异。我考虑过的一件事是在php中使用多维数组 - 使用$ machineID作为键然后存储时间戳在数组内部,关键点指向。
但是,由于我的查询逐行解析,我不确定该怎么做。
我有很多问题。
1)这是最有效的方法吗?我怀疑我的数据库表设计可能不是最好的。 2)确定某个machineID的时间戳差异的最佳方法是什么?
即使只是一个指向主题的指针,这会促使我以不同的方式思考这个问题会有所帮助 - 我不害怕做研究。谢谢!
答案 0 :(得分:0)
此解决方案假设您希望每台机器有一行,这可能是一个很大的假设!你可以使用now()函数来对抗最大值ts。如果你列出你期望的样本输出,我们可以调整答案。
您可以使用machineid和maxts以及之前的ts创建临时表。最后两列为null。为每个不同的machineid插入一行。然后将每行maxts更新为ts的最大值。更新每行的priorts是maxts之前的行max ts。然后你有你的数据
CREATE TABLE t1 (
reportnum int not null AUTO_INCREMENT PRIMARY KEY,
machineid char(10) not null,
ts TIMESTAMP
);
insert into t1 (machineid,ts) select 'AD3203','2012-11-18 06:32:28';
insert into t1 (machineid,ts) select 'AD3203','2012-11-19 04:00:15';
insert into t1 (machineid,ts) select 'BC4300','2012-11-19 04:00:15';
CREATE TABLE temp_rpt (
machineid char(10) not null,
maxts TIMESTAMP null,
priorts TIMESTAMP null
);
insert into temp_rpt (machineid,maxts,priorts)
select distinct machineid,null,null from t1;
UPDATE temp_rpt
SET maxts =
( SELECT MAX(ts)
FROM t1
WHERE machineid = temp_rpt.machineid
)
UPDATE temp_rpt
SET priorts =
( SELECT MAX(ts)
FROM t1
WHERE machineid = temp_rpt.machineid
and ts<temp_rpt.maxts
)
select * from temp_rpt;
+-----------+---------------------+---------------------+
| machineid | maxts | priorts |
+-----------+---------------------+---------------------+
| AD3203 | 2012-11-19 04:00:15 | 2012-11-18 06:32:28 |
| BC4300 | 2012-11-19 04:00:15 | NULL |
+-----------+---------------------+---------------------+
然后做你的日期数学
答案 1 :(得分:0)
我不确定我完全理解你要做的是什么,但是如果你想要计算表格中每一行与MachineID相同的时间差,我相信以下内容应该做你需要的
注意:这会找到每一行之间的时差(相同的MachineID,它与每个新的MachineID重置为00:00:00)。如果你想要第一行和最后一行之间的总和,你必须将TimestampDiff值相加。
DROP TABLE IF EXISTS tMachineReportsTest;
CREATE TABLE tMachineReportsTest (
ReportNum INT UNSIGNED NOT NULL AUTO_INCREMENT,
MachineID VARCHAR(6) NOT NULL,
Timestamp DATETIME NOT NULL,
PRIMARY KEY (ReportNum),
UNIQUE KEY (MachineId, Timestamp)
);
INSERT INTO tMachineReportsTest VALUES
(NULL,'AD3203','2012-11-18 06:32:28'),
(NULL,'AD3203','2012-11-18 10:45:13'),
(NULL,'BC4300','2012-11-19 04:00:15'),
(NULL,'AD3203','2012-11-19 11:19:23'),
(NULL,'BC4300','2012-11-20 06:08:01'),
(NULL,'AD3203','2012-11-20 18:04:45')
;
SET @machineId := NULL;
SET @lastMachineId := NULL;
SET @lastTimestamp := NULL;
SELECT x.ReportNum, x.MachineId, x.Timestamp, x.TimestampDiff FROM (
SELECT
tMRT.ReportNum,
tMRT.MachineId,
tMRT.Timestamp,
@lastMachineId := @machineId AS _lastMachineId,
@machineId := tMRT.machineId AS _machineId,
CASE WHEN @lastMachineId IS NULL OR @lastMachineId = @machineId THEN TIMEDIFF(tMRT.Timestamp, IFNULL(@lastTimestamp, tMRT.Timestamp)) ELSE '00:00:00' END TimestampDiff,
@lastTimestamp := tMRT.Timestamp lastTimestamp
FROM
tMachineReportsTest tMRT
ORDER BY
tMRT.MachineId, tMRT.Timestamp
) x
;
生成的查询的输出如下所示:
+-----------+-----------+---------------------+---------------+
| ReportNum | MachineId | Timestamp | TimestampDiff |
+-----------+-----------+---------------------+---------------+
| 1 | AD3203 | 2012-11-18 06:32:28 | 00:00:00 |
| 2 | AD3203 | 2012-11-18 10:45:13 | 04:12:45 |
| 4 | AD3203 | 2012-11-19 11:19:23 | 24:34:10 |
| 6 | AD3203 | 2012-11-20 18:04:45 | 30:45:22 |
| 3 | BC4300 | 2012-11-19 04:00:15 | 00:00:00 |
| 5 | BC4300 | 2012-11-20 06:08:01 | 26:07:46 |
+-----------+-----------+---------------------+---------------+
6 rows in set (0.01 sec)