SQL:它可以更好地解决吗?

时间:2015-06-04 21:48:51

标签: mysql sql

问我确定它可以:)

所以,

有一个简单的日志表:

CREATE TABLE `log` (
  `id` int(11) NOT NULL,  << AUTOINC
  `action` int(11) NOT NULL DEFAULT '0',
  `source` varchar(20) ,
  `time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, 
  `message` varchar(100) 
) ;

日志中充满了传感器数据,但重要的是传感器读取序列每1分钟调用一次。因此,应该每隔2分钟添加2个新行(2个传感器)(并非总是如此 - 就像传感器故障一样)。

这里几分钟前拍摄的实时日志表数据:

id   action source                  time                  message
9468    3   TEMP_28-021501c7b0ff    2015-06-04 23:28:03     24437
9467    3   TEMP_10-000802b59f3f    2015-06-04 23:28:02     24375
9466    3   TEMP_28-021501c7b0ff    2015-06-04 23:27:03     24437
9465    3   TEMP_10-000802b59f3f    2015-06-04 23:27:02     24375
9464    3   TEMP_28-021501c7b0ff    2015-06-04 23:26:03     24437
9463    3   TEMP_10-000802b59f3f    2015-06-04 23:26:02     24375
9462    3   TEMP_28-021501c7b0ff    2015-06-04 23:25:04     24437
9461    3   TEMP_10-000802b59f3f    2015-06-04 23:25:02     24312
9460    3   TEMP_28-021501c7b0ff    2015-06-04 23:24:03     24437
9459    3   TEMP_10-000802b59f3f    2015-06-04 23:24:02     24375

正如您所见,传感器每分钟都在读取,并在“消息”列中提供几乎相同的值。

关键在于我必须更改表格布局,以便在第一个传感器读取时间的时间内将两个“消息”都加上时间戳。

所以结果应该是这样的:

2015-06-04 23:28:03     24437 24375
2015-06-04 23:27:03     24437 24375
2015-06-04 23:26:03     24437 24375
etc

似乎我找到了解决方案,但看起来很糟糕:

SELECT l1.time as l1time,l1.message as l1mess , l2.message as l2mess, 
FROM log l1,log l2 
WHERE l1.source LIKE 'TEMP_10%' AND l2.source LIKE 'TEMP_28%' 
AND l2.id-l1.id=1 AND l1.action=3 AND l2.action=3 
AND ABS(TIMESTAMPDIFF(SECOND,l2.time,l1.time))<10;

有更好的解决方案,当然......

2 个答案:

答案 0 :(得分:0)

这很好用,语法更清晰,我认为效率更高:

select q0.`time`, q0.`message`, q1.`message` from
( select `id`, `time`, `message` from `log` where `source` = 'TEMP_10-000802b59f3f'
) as q0
,
( select `id`, `time`, `message` from `log` where `source` = 'TEMP_28-021501c7b0ff'
  ) as q1
where 
ABS(TIMESTAMPDIFF(SECOND,q0.`time`,q1.`time`))<10
and abs(q0.`id`-q1.`id`)=1;
  • 请注意,like运算符不是我们可以使用=
  • 的好选择
  • 如果action=3过滤器始终为true,请不要使用它,否则,将其放入内部查询q0和q1

这是一个实时DEMO

答案 1 :(得分:0)

您的查询格式更好:

SELECT l1.time as l1time,l1.message as l1mess, l2.message as l2mess, 
FROM log l1 JOIN
     log l2 
     ON l1.source LIKE 'TEMP_10%' AND l2.source LIKE 'TEMP_28%' AND
        l2.id - l1.id = 1 AND l1.action = 3 AND l2.action = 3 ABD
        ABS(TIMESTAMPDIFF(SECOND,l2.time, l1.time)) < 10;

这可能是编写查询的最佳方式。 。 。几乎。为了最好地使用索引(例如log(action, id)),这个on子句更好:

     ON l1.source LIKE 'TEMP_10%' AND l2.source LIKE 'TEMP_28%' AND
        l2.id = l1.id + 1 AND l1.action = 3 AND l2.action = 3 ABD
        ABS(TIMESTAMPDIFF(SECOND, l2.time, l1.time)) < 10;

我并非100%确定这实际上是你真正需要的。但您确实声称此查询适合您。