Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

> Nietypowe zapytanie - prośba o pomoc
topcio
post
Post #1





Grupa: Zarejestrowani
Postów: 140
Pomógł: 0
Dołączył: 14.01.2017

Ostrzeżenie: (0%)
-----


Witajcie.
Potrzebuję wykonać takie zapytanie do bazy:
Z rekordów od teraz wstecz o 1440 minut wyszukaj rekordy, które po sobie miały wartość 0. Jeśli znajdzie zwróci true.
Dla zobrazowania.

2018-03-04 13:30:00 1
2018-03-04 13:31:00 1
2018-03-04 13:32:00 1
2018-03-04 13:33:00 0 |
2018-03-04 13:34:00 0 |
2018-03-04 13:35:00 0 |
2018-03-04 13:36:00 0 |
2018-03-04 13:37:00 0 | Tu znalazł 10 rekordów po sobie więc zwraca TRUE
2018-03-04 13:38:00 0 |
2018-03-04 13:39:00 0 |
2018-03-04 13:40:00 0 |
2018-03-04 13:41:00 0 |
2018-03-04 13:42:00 0 |
2018-03-04 13:43:00 1
2018-03-04 13:44:00 1
2018-03-04 13:45:00 0 |
2018-03-04 13:46:00 0 | Ale tu już nie było 10 po sobie więc je pomija.
2018-03-04 13:47:00 1
2018-03-04 13:48:00 1

Nie mam pojęcia jak się zabrać za takie zapytanie
Proszę o pomoc bardziej doświadczonych.

Na razie mam tylko do wyszukiwania ile razy było 0

  1. public FUNCTION get_dvr_offline_status_count($dvr_mac_address) {
  2. $result = $this->sql->query("
  3. SELECT count(dvr_test_status)
  4. FROM (
  5. SELECT dvr_test_status
  6. FROM dvr_status
  7. WHERE dvr_test_status = 0
  8. AND dvr_status_dvr_mac_address = '$dvr_mac_address'
  9. AND dvr_status_timestamp BETWEEN NOW() - INTERVAL 1440 MINUTE AND NOW()
  10. ) count
  11. ");
  12. RETURN $result->fetch_row()[0];
  13. exit;
  14. }



Ten post edytował topcio 4.03.2018, 13:45:40
Go to the top of the page
+Quote Post
 
Start new topic
Odpowiedzi
trueblue
post
Post #2





Grupa: Zarejestrowani
Postów: 6 807
Pomógł: 1828
Dołączył: 11.03.2014

Ostrzeżenie: (0%)
-----


Żeby wyjaśnić, to od środka:

To zapytanie ponumeruje grupy. Grupa to zakres od wybranej godziny do ostatniej w puli. Czyli pierwsza grupa to rekordy od 0 do N, druga od 1 do N, trzecia od 2 do N, itd.:
  1. SELECT TIME_TO_SEC(TIMEDIFF(p2.godzina,(SELECT MIN(godzina) FROM pomiar))) AS grupa,p.godzina,p2.godzina AS godzina2,p.flaga
  2. FROM pomiar AS p, pomiar AS p2
  3. WHERE p.godzina>=p2.godzina


Teraz dodajemy licznik zmieniający się w ramach grupy. Licznik się przyda, bo chcemy wybrać z każdej grupy 10 rekordów. Nie możemy użyć aliasu grupa w warunkach, więc żeby go nie powtarzać, to obudowujemy w zapytanie:
  1. SELECT grupa,godzina2,flaga,
  2. IF(@poprzednia_grupa<>grupa,(SELECT @numer:=1),@numer:=@numer+1),
  3. IF(@poprzednia_grupa<>grupa,(SELECT @poprzednia_grupa:=grupa),NULL),
  4. @numer AS numer
  5. FROM
  6. (SELECT TIME_TO_SEC(TIMEDIFF(p2.godzina,(SELECT MIN(godzina) FROM pomiar))) AS grupa,p.godzina,p2.godzina AS godzina2,p.flaga FROM pomiar AS p, pomiar AS p2 WHERE p.godzina>=p2.godzina) AS tmp, (SELECT @numer:=1) AS numer, (SELECT @poprzednia_grupa:=-1) AS poprzednia_grupa


Tu już możemy zgrupować grupy wybierając z każdej tylko rekordy od numeru 1 do 10 i sumując ilość 0. To jest ostateczne zapytanie, które pokazuje ilość 0 od danej godziny włącznie + 9 kolejnych rekordów w przód:
  1. SELECT grupa,godzina2,SUM(flaga=0)
  2. FROM(
  3. SELECT grupa,godzina2,flaga,
  4. IF(@poprzednia_grupa<>grupa,(SELECT @numer:=1),@numer:=@numer+1),
  5. IF(@poprzednia_grupa<>grupa,(SELECT @poprzednia_grupa:=grupa),NULL),
  6. @numer AS numer
  7. FROM
  8. (SELECT TIME_TO_SEC(TIMEDIFF(p2.godzina,(SELECT MIN(godzina) FROM pomiar))) AS grupa,p.godzina,p2.godzina AS godzina2,p.flaga FROM pomiar AS p, pomiar AS p2 WHERE p.godzina>=p2.godzina) AS tmp, (SELECT @numer:=1) AS numer, (SELECT @poprzednia_grupa:=-1) AS poprzednia_grupa
  9. )
  10. AS tmp2 WHERE numer<=10
  11. GROUP BY grupa,godzina2


Gdybyś miał ciągłe godziny, to całość byłaby znacznie prostsza.
Go to the top of the page
+Quote Post

Posty w temacie


Reply to this topicStart new topic
2 Użytkowników czyta ten temat (2 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Aktualny czas: 15.10.2025 - 01:16