2017-02-22 9 views
0

я получил таблицу под названием «картинкой» со следующим содержанием:получить первую строку в час фактического дня

picID | Date | Time | pic | stationsID 
1  22.02.2017 08:03:10 dadadjadadk 4 
2  22.02.2017 08:13:10 ycycycycyc 4 
3  22.02.2017 08:45:10 dagxhgdgwetk 4 
4  22.02.2017 09:00:10 dadadjadadk 4 
5  22.02.2017 09:03:10 asdasdasdyxcyw 4 
6  22.02.2017 09:43:10 xvxvx  4 

С помощью следующего запроса я получил результат я хочу - получить только первую строку в час от фактического дня:

select p.* from pictures p where p.Date = CURDATE() AND p.Time = (select min(p2.Time) from pictures p2 where p2.Date = p.Date and hour(p2.Time) = hour(p.Time) and p2.StationsID = 4); 

1  22.02.2017 08:03:10 dadadjadadk 4 
4  22.02.2017 09:00:10 dadadjadadk 4 

Но мой запрос sql очень медленный. Любая идея, как оптимизировать мой запрос?

+0

Совет: дата и время магазин как единое целое. И некоррелированный подзапрос, вероятно, будет быстрее, чем коррелированный. – Strawberry

ответ

0

Ваш запрос Разумно:

select p.* 
from pictures p 
where p.Date = CURDATE() and 
     p.StationsID = 4 and -- added this condition because it seems needed 
     p.Time = (select min(p2.Time) 
       from pictures p2 
       where p2.Date = p.Date and hour(p2.Time) = hour(p.Time) and 
         p2.StationsID = 4 
       ); 

Для этого запроса вы хотите индексов. Я бы порекомендовал: pictures(Date, StationsId, Time).

+0

немного быстрее: P – Lukas

+0

@Lukas. , , Насколько быстрее? –

+0

не намного быстрее, но я нашел решение для своей проблемы. См. Ниже – Lukas

0
DROP TABLE IF EXISTS pictures; 

CREATE TABLE pictures 
(picID INT NOT NULL AUTO_INCREMENT PRIMARY KEY 
,dt DATETIME NOT NULL 
,pic VARCHAR(20) NOT NULL 
,stationsID INT NOT NULL 
); 

INSERT INTO pictures VALUES 
(1,'2017-02-22 08:03:10' , 'dadadjadadk',4), 
(2,'2017-02-22 08:13:10' , 'ycycycycyc',4), 
(3,'2017-02-22 08:45:10' , 'dagxhgdgwetk',4), 
(4,'2017-02-22 09:00:10' , 'dadadjadadk',4), 
(5,'2017-02-22 09:03:10' , 'asdasdasdyxcyw',4), 
(6,'2017-02-22 09:43:10' , 'xvxvx',4); 


SELECT x.* 
    FROM pictures x 
    JOIN 
    (SELECT MIN(dt) dt 
     FROM pictures 
     GROUP 
      BY DATE_FORMAT(dt,'%Y-%m-%d %h') 
    ) y 
    ON y.dt = x.dt; 
+-------+---------------------+-------------+------------+ 
| picID | dt     | pic   | stationsID | 
+-------+---------------------+-------------+------------+ 
|  1 | 2017-02-22 08:03:10 | dadadjadadk |   4 | 
|  4 | 2017-02-22 09:00:10 | dadadjadadk |   4 | 
+-------+---------------------+-------------+------------+ 
+0

Спасибо за ваш ответ, но изменение структуры моего стола было бы последним вариантом для меня:/ – Lukas

+0

@Lukas Очень жаль. – Strawberry

0

нашел хорошее решение:

SELECT p.* FROM pictures p JOIN (
SELECT MIN(Time) as Time, MIN(picID) as picID FROM pictures 
WHERE StationsID = 4 AND 
Date = CURDATE() 
GROUP BY HOUR(Time)) p1 
ON p.picID = p1.picID;