Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

 
Reply to this topicStart new topic
> [MySQL][PHP] MAX z przedziału
brzanek
post 20.11.2018, 22:11:28
Post #1





Grupa: Zarejestrowani
Postów: 427
Pomógł: 0
Dołączył: 8.11.2012

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


Mam kolejny kłopot.
Powiedzcie mi dlaczego to nie chce mi zadziałać tak jak powinno.
Mam kod
  1. $start = strtotime("tomorrow 08:00");
  2. $koniec = strtotime("tomorrow 19:00");
  3.  
  4. $result = $mysqli->query("
  5. SELECT MAX(hwindGust) AS wiatrsr, t.hwindBearing,zt.kierunek, hid_miasto, htime, t.hwindGust,zw.sila_wiatru
  6. FROM prognoza_godzinowa AS t, kierunek_wiatru AS zt, sila_wiatru AS zw
  7. WHERE t.hwindBearing>=zt.od AND t.hwindBearing<zt.do AND t.hwindGust>=zw.od AND t.hwindGust<zw.do AND htime BETWEEN '".$start."' AND '".$koniec."' AND hid_miasto =9
  8. ");
  9. while ( $row = mysqli_fetch_array($result) ) {
  10. $wiatr = ''.round($row['wiatrsr'],1).'';
  11. }
  12. echo '<p>'.$wiatr.'</p>';

Kod powinien oddać najwyższą wartość w polu wiatrsr z danego przedziału zawartego pomiędzy $start a $koniec ale zwraca tylko pierwszą wartość z bazy i nie jest to najwyższa z danego okresu - dlaczego?

Takie zapytanie działa prawidłowo
  1. $result = $mysqli->query("SELECT MAX(hwindGust) AS wiatrsr FROM prognoza_godzinowa WHERE htime BETWEEN '".$start."' AND '".$koniec."' AND hid_miasto=9");
  2. while ( $row = mysqli_fetch_array($result) ) {
  3. echo '<p>'.round($row['wiatrsr'],1).'</p>';
  4. }

Ale potrzebne mi to w pierwszym kodzie.

Sory kod działa ale pokazuje inny błąd.
Obecnie najwyższa wartość pobierana w tym przedziale czasowym z bazy danych to wiatrsr = 77
Natomiast sila_wiatru przy 77 daje kolor czerwony a wyświetla z (powinno być czerwony)
sila_wiatru pobierana jest jako pierwsza z tego przedziału a nie jak powinno być maksymalna.
Jak to naprawić?

Ten post edytował brzanek 20.11.2018, 22:38:00
Go to the top of the page
+Quote Post
Pyton_000
post 20.11.2018, 22:40:44
Post #2





Grupa: Zarejestrowani
Postów: 8 068
Pomógł: 1414
Dołączył: 26.10.2005

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


zamiast MAX użyj po prostu
Kod
ORDER BY `hwindGust` LIMIT 1
Go to the top of the page
+Quote Post
brzanek
post 21.11.2018, 07:00:22
Post #3





Grupa: Zarejestrowani
Postów: 427
Pomógł: 0
Dołączył: 8.11.2012

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


Dzięki zadziałało
Ale teraz mam inny problem muszę połączyć kilka wartości w jednym zapytaniu
  1. $result = $mysqli->query("
  2. SELECT t.SUM(hcloudCover),zt.nazwa_ikony, hid_miasto, htime
  3. FROM prognoza_godzinowa AS t, ikona_dzien AS zt
  4. WHERE htime BETWEEN '".$start."' AND '".$koniec."' AND t.SUM(hcloudCover)>=zt.od AND t.SUM(hcloudCover)<zt.do AND hid_miasto =1
  5. ORDER BY htemperature DESC LIMIT 1
  6. ");
  7. while ( $row = mysqli_fetch_array($result) ) {
  8. $tempmax = ''.$row['htemperature'].'';
  9. $imagee = imagecreatefrompng('http://brzanek.webd.pl/2019/strona/prognoza/images/ikony'.$row['nazwa_ikony'].'.png');
  10. }

Tak wywala błąd. Potrzebuję sumę hcloudCover podstawi do nazwa_ikony i jednocześnie wyciągnąć najwyższą wartość htemperature z danego przedziału $start / $koniec
Go to the top of the page
+Quote Post
Neutral
post 21.11.2018, 14:08:35
Post #4





Grupa: Zarejestrowani
Postów: 286
Pomógł: 46
Dołączył: 10.01.2016

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


  1. SELECT SUM(tx.hcloudcover) AS summed, zty.name_icon, zty.hid_city, zty.htime FROM t AS tx, zt AS zty
  2. WHERE tx.htime BETWEEN '09:00:00' AND '15:00:00' AND zty.hid_city = 1 HAVING summed >= 1 AND summed < 200 ORDER BY 1 DESC LIMIT 1;


  1. while($row = $result->fetch_array(MYSQLI_NUM)) {
  2. print_r($row);
  3. }


Ten post edytował Neutral 21.11.2018, 14:11:43
Go to the top of the page
+Quote Post
brzanek
post 21.11.2018, 21:48:50
Post #5





Grupa: Zarejestrowani
Postów: 427
Pomógł: 0
Dołączył: 8.11.2012

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


Ten kod nie działa. Podstawiłem tam swoje dane ale nic z tego nie wyszło. Nie w nim kilku potrzebnych parametrów takich jak np. htemperature.

Kombinuję kombinuję i nic mi nie wychodzi.
Doszedłem do tego
  1. $result = $mysqli->query("
  2. SELECT hwindBearing,zt.kierunek, hwindGust,zw.sila_wiatru, hid_miasto, htime, SUM(hcloudCover) AS hcloudCover,di.nazwa_ikony FROM prognoza_godzinowa, kierunek_wiatru AS zt, sila_wiatru AS zw, ikona_dzien AS di WHERE htime BETWEEN '1542830400' AND '1542916800' AND hwindBearing>=zt.od AND hwindBearing<zt.do AND hwindGust>=zw.od AND hwindGust<zw.do AND hcloudCover>=di.zachmurzenie_od AND hcloudCover<di.zachmurzenie_do AND hid_miasto =1 ORDER BY hwindGust DESC LIMIT 1
  3. ");

Wartość z SUM(hcloudCover) jest ok ale nie jest dobrze przypisywana do hcloudCover>=di.zachmurzenie_od AND hcloudCover<di.zachmurzenie_do

Ten post edytował brzanek 21.11.2018, 21:49:59
Go to the top of the page
+Quote Post
trueblue
post 21.11.2018, 22:09:14
Post #6





Grupa: Zarejestrowani
Postów: 6 761
Pomógł: 1822
Dołączył: 11.03.2014

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


Nie będzie działać, bo to, że dałeś alias dla sumy o nazwie kolumny, to nie znaczy, że zostanie podstawiony do klauzuli WHERE.
Poczytaj trochę o SQL - szczególnie jak działają funkcje grupujące w połączeniu z WHERE.
Bardzo prawdopodobne, że sumę musisz nałożyć na dodatkowe zapytanie, którego podzapytaniem będzie to z WHERE i zakresami, ale nie wiem, bo nie mam kompletnie pojęcia co chcesz uzyskać. Na pewno czytelność ułatwiłoby trafne dobieranie aliasów dla tabel, np. dla kierunek_wiatru - kw, a nie zt. O aliasach też poczytaj, bo to nie magia, którą musisz przepisywać bezmyślnie z przykładu.


--------------------
Go to the top of the page
+Quote Post
brzanek
post 21.11.2018, 22:16:46
Post #7





Grupa: Zarejestrowani
Postów: 427
Pomógł: 0
Dołączył: 8.11.2012

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


Chcę aby sumowana wartość hcloudCover z przedziału od do (htime BETWEEN '1542830400' AND '1542916800') przypisana była do innej tabeli i zastąpiona odpowiednią wartością z zakresu zachmurzenie_od - zachmurzenie_do
Zamiast sumowanej liczby nazwa ikony np: slonce itp


Takie zapytanie
  1. SELECT hwindBearing,zt.kierunek, hwindGust,zw.sila_wiatru, hid_miasto, htime, SUM(hcloudCover) AS hcloudCover,di.nazwa_ikony FROM prognoza_godzinowa, kierunek_wiatru AS zt, sila_wiatru AS zw, ikona_dzien AS di WHERE htime BETWEEN '1542830400' AND '1542916800' AND hwindBearing>=zt.od AND hwindBearing<zt.do AND hwindGust>=zw.od AND hwindGust<zw.do AND hcloudCover>=di.zachmurzenie_od AND hcloudCover<di.zachmurzenie_do AND hid_miasto =1 ORDER BY hwindGust DESC LIMIT 1

Daje taki wynik

Suma zachmurzenia (hcloudCover) = 94 więc ikona powinna być slonce_mala_chmurka a nie samo slonce.

Ten post edytował brzanek 21.11.2018, 22:20:32
Go to the top of the page
+Quote Post
trueblue
post 21.11.2018, 22:34:00
Post #8





Grupa: Zarejestrowani
Postów: 6 761
Pomógł: 1822
Dołączył: 11.03.2014

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


Suma w takim przypadku wykonuje się na rekordach, które zostały ograniczone przez WHERE. Dopiero na nich.
Masz wykonać najpierw zapytanie wiążące zachmurzenie z zakresami, na tym kolejne zapytanie już z sumą i dopiero wykonać ORDER i LIMIT.


--------------------
Go to the top of the page
+Quote Post
brzanek
post 21.11.2018, 22:42:28
Post #9





Grupa: Zarejestrowani
Postów: 427
Pomógł: 0
Dołączył: 8.11.2012

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


Czyli co muszę najpierw to dać
  1. $result = $mysqli->query("
  2. SELECT SUM(hcloudCover) AS zachmurzeniesuma, htime FROM prognoza_godzinowa WHERE htime BETWEEN '1542830400' AND '1542916800' AND hid_miasto =1 ORDER BY hcloudCover DESC LIMIT 1
  3. ");
  4. while ( $row = mysqli_fetch_array($result) ) {
  5. $zachmurzenie = ''.$row['zachmurzeniesuma'].'';
  6. }
  7. echo ''.$zachmurzenie.'';

Potem dopiero to drugie?
Czy mamto zrobić w jednym zapytaniu w jakiś inny sposób.
Go to the top of the page
+Quote Post
Neutral
post 22.11.2018, 00:18:31
Post #10





Grupa: Zarejestrowani
Postów: 286
Pomógł: 46
Dołączył: 10.01.2016

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


  1. SHOW CREATE TABLE brzanek\G
  2. *************************** 1. row ***************************
  3. TABLE: brzanek
  4. CREATE TABLE: CREATE TABLE `brzanek` (
  5. `id` int(11) NOT NULL AUTO_INCREMENT,
  6. `htime` time DEFAULT NULL,
  7. `hwindBearing` int(11) DEFAULT NULL,
  8. `from` int(11) DEFAULT NULL,
  9. `to` int(11) DEFAULT NULL,
  10. `hwindgust` int(11) DEFAULT NULL,
  11. `from1` int(11) DEFAULT NULL,
  12. `to1` int(11) DEFAULT NULL,
  13. `hcloudcover` int(11) DEFAULT NULL,
  14. `clouds_from` int(11) DEFAULT NULL,
  15. `clouds_to` int(11) DEFAULT NULL,
  16. `hid_city` int(11) DEFAULT NULL,
  17. PRIMARY KEY (`id`)
  18. ) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci

  1. SELECT * FROM brzanek;

Kod
+----+----------+--------------+------+------+-----------+-------+------+-------------+-------------+-----------+----------+
| id | htime    | hwindBearing | from | to   | hwindgust | from1 | to1  | hcloudcover | clouds_from | clouds_to | hid_city |
+----+----------+--------------+------+------+-----------+-------+------+-------------+-------------+-----------+----------+
|  1 | 10:10:20 |            5 |   10 |    4 |         4 |     2 |    1 |           7 |           8 |         9 |       25 |
|  2 | 18:17:01 |           90 |  120 |    4 |         6 |     2 |   45 |           7 |           9 |         9 |       15 |
|  3 | 22:01:01 |           12 |   12 |    1 |         0 |     3 |   28 |          27 |          55 |        42 |       16 |
|  4 | 15:00:00 |           10 |   56 |    6 |        90 |     2 |    1 |           0 |          10 |        60 |       59 |
|  5 | 15:00:00 |           57 |   56 |  100 |        90 |     2 |  110 |           0 |          10 |        60 |       59 |
+----+----------+--------------+------+------+-----------+-------+------+-------------+-------------+-----------+----------+

  1. SELECT *, sum(hcloudcover) AS hcloudcover FROM (SELECT hwindBearing, hwindgust, hid_city, htime, id, clouds_from, clouds_to FROM brzanek WHERE htime BETWEEN '10:00:00' AND '23:00:00' AND hwindbearing>=`from` AND hwindbearing<`to` AND hwindgust>=from1 AND hwindgust<to1 AND hid_city = 59) AS vv, brzanek AS brzan WHERE hcloudcover>=vv.clouds_from AND hcloudcover<vv.clouds_to\G

Kod
*************************** 1. row ***************************
hwindBearing: 57
   hwindgust: 90
    hid_city: 59
       htime: 15:00:00
          id: 5
clouds_from: 10
   clouds_to: 60
          id: 3
       htime: 22:01:01
hwindBearing: 12
        from: 12
          to: 1
   hwindgust: 0
       from1: 3
         to1: 28
hcloudcover: 27
clouds_from: 55
   clouds_to: 42
    hid_city: 16
hcloudcover: 27


Musisz stworzyć po prostu delivered table do tego (poczytaj o tym m.in. w dokumentacji MySQL). Pokazałem Ci kierunek, dalej pisz sam. Napisałem to na jednej tabeli, jeśli chcesz łatwo zmodyfikujesz ten kod na więcej tabel. "\G" na końcu oznacza inne formatowanie rezultatu z zapytania niż standardowe. Jest to pomocne, jeśli tabela się rozjedża lub "nie mieści na ekranie".

Ten post edytował Neutral 22.11.2018, 00:27:30
Go to the top of the page
+Quote Post
brzanek
post 22.11.2018, 08:36:19
Post #11





Grupa: Zarejestrowani
Postów: 427
Pomógł: 0
Dołączył: 8.11.2012

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


Trochę tego nie kumam
AND hid_city = 59) AS vv, brzanek AS brzan WHERE hcloudcover>=vv.clouds_from AND hcloudcover<vv.clouds_to\G
Skąd w twoim zapytaniu vv oraz brzan?
Nie wiem czy rozumiesz mój problem bo twój przykład chyba nie pokazuje tego co chcę osiągnąć albo ja czegoś tu nie czaję.
Go to the top of the page
+Quote Post
viking
post 22.11.2018, 08:59:10
Post #12





Grupa: Zarejestrowani
Postów: 6 365
Pomógł: 1114
Dołączył: 30.08.2006

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


https://en.wikipedia.org/wiki/Alias_(SQL)


--------------------
Go to the top of the page
+Quote Post
brzanek
post 22.11.2018, 09:51:19
Post #13





Grupa: Zarejestrowani
Postów: 427
Pomógł: 0
Dołączył: 8.11.2012

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


No fajnie tylko powiedzcie mi gdzie ja w tym wszystkim mam użytą funkcję SUM bo właśnie o to mi chodzi.
Podane przez was przykłady do niczego mnie nie prowadzą.
Go to the top of the page
+Quote Post
nospor
post 22.11.2018, 11:14:56
Post #14





Grupa: Moderatorzy
Postów: 36 447
Pomógł: 6292
Dołączył: 27.12.2004




Naprawde nie widzisz SUM w tym zapytaniu?

A to:
sum(hcloudcover) AS hcloudcover
to niby co? Wrozka zebuszka?


--------------------

"Myśl, myśl, myśl..." - Kubuś Puchatek || "Manual, manual, manual..." - Kubuś Programista
"Szukaj, szukaj, szukaj..." - Kubuś Odkrywca || "Debuguj, debuguj, debuguj..." - Kubuś Developer

Go to the top of the page
+Quote Post
brzanek
post 22.11.2018, 11:47:16
Post #15





Grupa: Zarejestrowani
Postów: 427
Pomógł: 0
Dołączył: 8.11.2012

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


Faktycznie jest ale mam z tym sposobem problem bo nic mi nie wychodzi.
Myślałem, że może coś takiego zadziała
  1. $start = strtotime("tomorrow 08:00");
  2. $koniec = strtotime("tomorrow 22:00");
  3.  
  4. $result = $mysqli->query("
  5. SELECT SUM(hcloudCover) AS zachmurzeniesuma, htime FROM prognoza_godzinowa WHERE htime BETWEEN '".$start."' AND '".$koniec."' AND hid_miasto =1 ORDER BY hcloudCover DESC LIMIT 1
  6. ");
  7. while ( $row = mysqli_fetch_array($result) ) {
  8. $zachmurzenie = ''.$row['zachmurzeniesuma'].'';
  9. }
  10.  
  11. $result = $mysqli->query("
  12. SELECT nazwa_ikony, zachmurzenie_od, zachmurzenie_do, opady_od, opady_do
  13. FROM ikona_dzien
  14. WHERE '".$zachmurzenie."'>=zachmurzenie_od AND '".$zachmurzenie."'<zachmurzenie_do ORDER BY nazwa_ikony
  15. ");
  16. while ( $row = mysqli_fetch_array($result) ) {
  17. $nazwaikony = ''.$row['nazwa_ikony'].'';
  18. }
  19. echo '<p>'.$zachmurzenie.'</p>';
  20. echo '<p>'.$nazwaikony.'</p>';

Ale też błędnie pokazuje nazwe_ikony
Za każdym razem pokazuje tylko pierwszą.
Go to the top of the page
+Quote Post
nospor
post 22.11.2018, 11:59:13
Post #16





Grupa: Moderatorzy
Postów: 36 447
Pomógł: 6292
Dołączył: 27.12.2004




Cytat
Za każdym razem pokazuje tylko pierwszą.

A ile ma pokazywac jak za kazdym razem w petli nadpisujesz te ikone?


--------------------

"Myśl, myśl, myśl..." - Kubuś Puchatek || "Manual, manual, manual..." - Kubuś Programista
"Szukaj, szukaj, szukaj..." - Kubuś Odkrywca || "Debuguj, debuguj, debuguj..." - Kubuś Developer

Go to the top of the page
+Quote Post
Neutral
post 22.11.2018, 12:08:32
Post #17





Grupa: Zarejestrowani
Postów: 286
Pomógł: 46
Dołączył: 10.01.2016

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


  1. SELECT *, SUM(hcloudcover) AS hcloudcover FROM (<<tutaj wstaw, TO co BYło w mojej ostatniej odpowiedzi>>) AS vv, brzanek WHERE brzanek.hcloudcover>=vv.clouds_from AND brzanek.hcloudcover<vv.clouds_to\G


Alias na delivered table "vv", oznacza odwołanie się do tego rezultatu z zapytania. Napisz sobie w CLI (Command Line Interface) te zapytanie, które ma przypisany alias "vv" i zobaczysz wtedy, że z tych danych wyciągasz tym pierwszym zapytaniem te dane, czyli "*, SUM(hcloudcover) as hcloudcover". Wszystko, czyli "*" wyciągasz z tabeli z przypisanym alias'em. Następnie sumę, ale nie z zapytania z alias'em, tylko już z tabeli "brzanek". Oddaje to ostatni warunek po "WHERE". Weź sumę z tabeli "brzanek" osobno oraz dane z delivered table z przypisanym alias'em "vv" też osobno. Dalej porównaj te dane ze sobą na samym końcu (mówi to klauzula "WHERE" po alias'ie "vv".
Go to the top of the page
+Quote Post
brzanek
post 22.11.2018, 12:57:24
Post #18





Grupa: Zarejestrowani
Postów: 427
Pomógł: 0
Dołączył: 8.11.2012

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


Pewnie macie rację ale zrobiłem to troszkę inaczej
  1. $start = strtotime("tomorrow 08:00");
  2. $koniec = strtotime("tomorrow 22:00");
  3.  
  4. $result = $mysqli->query("
  5. SELECT SUM(hcloudCover) AS zachmurzeniesuma, htime FROM prognoza_godzinowa WHERE htime BETWEEN '".$start."' AND '".$koniec."' AND hid_miasto =1 ORDER BY hcloudCover DESC LIMIT 1
  6. ");
  7. while ( $row = mysqli_fetch_array($result) ) {
  8. $zachmurzenie = ''.$row['zachmurzeniesuma'].'';
  9. }
  10.  
  11. $result = $mysqli->query("
  12. SELECT SUM(hprecipIntensity) AS sumaopadow, htime FROM prognoza_godzinowa WHERE htime BETWEEN '".$start."' AND '".$koniec."' AND hid_miasto =1 ORDER BY hprecipIntensity DESC LIMIT 1
  13. ");
  14. while ( $row = mysqli_fetch_array($result) ) {
  15. $opady = ''.$row['sumaopadow'].'';
  16. }
  17.  
  18. $result = $mysqli->query("
  19. SELECT *
  20. FROM ikona_dzien
  21. WHERE ".$zachmurzenie." BETWEEN zachmurzenie_od AND zachmurzenie_do AND ".$opady." BETWEEN opady_od AND opady_do
  22. ");
  23. while ( $row = mysqli_fetch_array($result) ) {
  24. $nazwaikony = ''.$row['nazwa_ikony'].'';
  25. }
  26. echo '<p>'.$zachmurzenie.'</p>';
  27. echo '<p>'.$opady.'</p>';
  28. echo '<p>'.$nazwaikony.'</p>';

Działa tylko teraz będę miał więcej zapytań do bd.
Go to the top of the page
+Quote Post

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

 



RSS Wersja Lo-Fi Aktualny czas: 19.04.2024 - 23:53