Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Złożone zapytanie
Forum PHP.pl > Forum > Bazy danych
misiekdg
Mam uruchomiony serwer MySql na którym zapisuje się co się dzieje z ogrzewaniem w domu.
Jedna tabela "piec" przechowuje informację kiedy piec się uruchomił a kiedy wyłączył.

Zapis jest w postaci:

Id / wartość / data

1 / 1 / 2019-11-01 02:30:00 - informacja o włączeniu się pieca
2 / 0 / 2019-11-01 02:53:00 - informacja o wyłączeniu się pieca
3 / 0 / 2019-11-01 03:01:00 - piec nadal wyłączony
4 / 1 / 2019-11-01 03:08:00 - uruchomienie pieca
5 / 1 / 2019-11-01 03:09:00 - piec nadal pracuje
....

itd

czasami system wysyła kontrolne ramki tak że w ciągu jednego cyklu grzania pojawiają się w tablicy 2-3 wpisy pod rząd z informacją że piec pracuje. tak samo kiedy piec jest wyłączony.

Chciałem stworzyć zapytanie, które będzie mi liczyło czas pracy pieca w danym dniu - czyli sumowało wszystkie czasy od 1 do 0, ale nie wiem czy jest to możliwe do wykonania w jednym zapytaniu. Zastanawiam się czy np nie prościej by było np przy zapisywaniu 0 do tablicy sprawdzać czy ostatni wpis to 1, zliczać różnicę w czasie i zapisywać wynik do innej tabeli. No ale to rozwiązanie też nie jest bez wad...
Może ktoś już starał się rozwiązać podobny problem.
Z góry dzięki za rady.
Azek
Trzymaj:
  1. CREATE TABLE `piec` (
  2. `id` int(11) NOT NULL AUTO_INCREMENT,
  3. `wartosc` tinyint(4) DEFAULT NULL,
  4. `data` datetime DEFAULT NULL,
  5. PRIMARY KEY (`id`),
  6. UNIQUE KEY `id_UNIQUE` (`id`)
  7. ) ENGINE=InnoDB;
  8.  
  9. INSERT INTO `piec` VALUES
  10. (1,0,'2019-01-01 01:00:00'),
  11. (2,1,'2019-01-01 02:00:00'),
  12. (3,1,'2019-01-01 03:30:00'),
  13. (4,1,'2019-01-01 04:00:00'),
  14. (5,0,'2019-01-01 05:00:00'),
  15. (6,1,'2019-01-01 06:00:00'),
  16. (7,0,'2019-01-01 07:00:00'),
  17. (8,1,'2019-01-02 01:00:00'),
  18. (9,0,'2019-01-02 02:00:00'),
  19. (10,0,'2019-01-02 03:00:00'),
  20. (11,1,'2019-01-02 04:00:00'),
  21. (12,0,'2019-01-02 05:00:00'),
  22. (13,1,'2019-01-02 06:00:00');

I zapytanie:
  1. SET @dzien:='2019-01-02';
  2. SET @i1:=0;
  3. SET @i2:=0;
  4. SELECT SEC_TO_TIME(SUM(TIME_TO_SEC(TIMEDIFF(data1, data2)))) AS 'Laczny czas' FROM
  5. (SELECT @i1:=@i1+1 AS id1, p1.DATA AS data1, p2.wartosc - p1.wartosc AS zmiana1 FROM piec AS p1 INNER JOIN piec AS p2 ON p1.id = (p2.id + 1) WHERE (p2.wartosc <> p1.wartosc) AND DATE (p1.DATA) = @dzien ) AS tab1
  6. INNER JOIN
  7. (SELECT @i2:=@i2+1 AS id2, p3.DATA AS data2, (p4.wartosc - p3.wartosc) AS zmiana2 FROM piec AS p3 INNER JOIN piec AS p4 ON p3.id = (p4.id + 1) WHERE (p3.wartosc <> p4.wartosc) AND DATE(p3.DATA) = @dzien) AS tab2
  8. ON tab1.id1 = tab2.id2 + 1 WHERE `zmiana1` = 1
trueblue
Na danych autora otrzymałem NULL.

Utrudnieniem będzie przełom dnia kiedy była zachowana ciągłość pracy pieca. Wydaje mi się, że lepszym rozwiązaniem będzie tu użycie skryptu.
Azek
Cytat(trueblue @ 13.11.2019, 10:42:25 ) *
Utrudnieniem będzie przełom dnia kiedy była zachowana ciągłość pracy pieca. Wydaje mi się, że lepszym rozwiązaniem będzie tu użycie skryptu.

Też tak myślę. Znacznie łatwiej i prościej można to zrobić np. w PHP. Wtedy znika problem braku któregoś z id, można też ładnie zrobić podgląd całego tygodnia i obsłużyć przypadek, że piec działa na przełomie dwóch czy nawet więcej dni. Ale pytanie było, czy jest możliwe zrobienie tego w jednym zapytaniu. Odpowiedź: tak, jest to możliwe, aczkolwiek ma pewne ograniczenia.
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2020 Invision Power Services, Inc.