Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [MySQL][PHP] Łączenie wyników w jednej tabeli
Forum PHP.pl > Forum > Przedszkole
DreamCatcher
Mam 2 tabele z kursami walut, których struktura przedstawia się następująco:

WALUTA (łącznie 5 walut, które są stałe)
id
nazwa
kod

WARTOSC
id
waluta_id
kurs
data

Wykonuję zapytanie sql, które pobiera z bazy danych ostatnie 5 wyników za pomocą LEFT JOIN i wyświetla tabelę z kursami:
  1. SELECT * FROM waluta JOIN LEFT value ON valuta.id=wartosc.waluta_id ORDER BY wartosc.DATA DESC LIMIT 0,5


Następnie za pomocą skryptu php pobieram dane ze strony z kursami walut.
W zmiennej $waluty mam wówczas tablicę postaci:
  1. Array ( [USD] => Array ( [name] => dolar amerykański [code] => USD [amount] => 2.80 [date] => 2011-05-27 ) [EUR] => Array ( [name] => euro [code] => EUR [amount] => 3.98 [date] => 2011-05-27 ) [CHF] => Array ( [name] => frank szwajcarski [code] => CHF [amount] => 3.26 [date] => 2011-05-27 ) [GBP] => Array ( [name] => funt szterling [code] => GBP [amount] => 4.59 [date] => 2011-05-27 ) [RUB] => Array ( [name] => rubel rosyjski [code] => RUB [amount] => 0.10 [date] => 2011-05-27 ) )


Teraz chciałbym wyświetlić w nowej tabeli ostatnich 5 kursów walut oraz 5 nowych koło siebie (tych niedawno pobranych, które znajdują się w tablicy), dodatkowo policzyć zmianę procentową między starym kursem, a nowym dla każdej waluty (zmiana_procentowa = 100%-stary_kurs*100%/nowy_kurs), tak aby widok był mniej więcej taki:

Lp. | Nazwa | Kod | Kurs | Data | Nowy kurs | Aktualna data | Zmiana procentowa

W jaki sposób tego dokonać? Jest możliwość, aby pominąć zapisywanie do tabeli WARTOSC nowych kursów? Ktoś pomoże?
Gość
Łatwiej by było chyba jednak zapisać te pobrane wartości z tablicy (array(usd,eur,...)) w bazie danych w tabeli wartosc. Pozniej policzyc zmiany procentowe dla kazdej waluty, a dopiero pozniej za pomoca zapytania SQL wypelnic tabele danymi. Ale jak by wygladalo takie zapytanie, które pobiera odpowiednie informacje, nie wiem. Jakas tega glowa musi ci pomoc.
A jakie masz dane (chodzi mi o zawartosc) w tabeli WARTOSC?
DreamCatcher
Tabela WARTOSC ma w tej chwili następujące dane:

id waluta_id kurs data
1 1 2.76 2011-04-10
2 2 4.07 2011-04-10
3 3 3.09 2011-04-10
4 4 4.66 2011-04-10
5 5 0.10 2011-04-10
9 1 2.91 2011-05-02
10 2 3.85 2011-05-02
11 3 3.19 2011-05-02
12 4 4.47 2011-05-02
13 5 0.12 2011-05-02

A zatem jakiego zapytania SQL użyć, aby policzyć te zmiany procentowe dla każdej waluty i wyświetlić wyniki w postaci:

Lp. | Nazwa | Kod | Kurs | Data | Nowy kurs | Aktualna data | Zmiana procentowa
1 dolar USD 2.76 2011-04-10 2.91 2011-05-27 1.05 %
Tomal40
Przykładowe rozwiązanie:


Biorę 3 tabele:

WALUTA:
id
nazwa
kod

WARTOSC
id
walutaid
kurs
data

WARTOSCNOWA
walutaid
nowykurs
aktualnadata

W celu prostoty tabela wartosc zawiera tylko 5 wejściowych rekordów, każdy z inną walutą natomiast tabela wartoscnowa zawiera 5 rekordów ze zmiennej $waluty obrazującej aktualne kursy 5 walut.
Wówczas zapytanie wygląda tak:

  1. SELECT waluta.id AS LP,nazwa, waluta.kod AS kod, wartosc.kurs AS kurs, wartosc.DATA AS dataa, wartoscnowa.nowykurs AS nowykurs, wartoscnowa.aktualnadata AS aktualnadata
  2. FROM wartosc, waluta, wartoscnowa
  3. WHERE waluta.id = wartosc.id AND wartosc.walutaid = wartoscnowa.walutaid;


Dodatkowo podczas odczytu rekordów z MYSQL skrypt PHP tworzy mi dodatkową kolumnę Zmiana procentowa i to na tym poziomie przez manipulację zmiennymi zapełniam ją wartościami:
  1. <?php
  2. require_once('c:\xampp\security\mysqli_connects.php');
  3.  
  4. $q = "SELECT waluta.id AS LP,nazwa, waluta.kod AS kod, wartosc.kurs AS kurs, wartosc.data AS dataa, wartoscnowa.nowykurs AS nowykurs, wartoscnowa.aktualnadata AS aktualnadata
  5. FROM wartosc, waluta, wartoscnowa
  6. WHERE waluta.id = wartosc.id and wartosc.walutaid = wartoscnowa.walutaid";
  7. $r = @mysqli_query ($dbc, $q);
  8. $num = mysqli_num_rows($r);
  9.  
  10. echo '<table align="center" cellspacing="3" cellpadding="3" width="75%">
  11. <tr>
  12. <td align="left"><b>LP</b></td>
  13. <td align="left"><b>Nazwa</b></td>
  14. <td align="left"><b>Kod</b></td>
  15. <td align="left"><b>Kurs</b></td>
  16. <td align="left"><b>Data</b></td>
  17. <td align="left"><b>Nowykurs</b></td>
  18. <td align="left"><b>AktualnaData</b>
  19. <td align="left"><b>Zmiana procentowa</td>
  20. </tr>
  21. ';
  22.  
  23.  
  24.  
  25. while ($row = mysqli_fetch_array($r, MYSQLI_ASSOC)) {
  26. $a=0.00;
  27. $b=0.00;
  28. $a=$row['kurs'];
  29. $b=$row['nowykurs'];
  30. $d=number_format((1-($a/$b))*100, 2);
  31.  
  32. echo '<tr>
  33. <td align = "left">' . $row['LP'] . '</td>
  34. <td align = "left">' . $row['nazwa'] . '</td>
  35. <td align = "left">' . $row['kod'] . '</td>
  36. <td align = "left">' . $row['kurs'] . '</td>
  37. <td align = "left">' . $row['dataa'] . '</td>
  38. <td align = "left">' . $row['nowykurs'] . '</td>
  39. <td align = "left">' . $row['aktualnadata'] . '</td>
  40. <td align = "left">'. $d .'%'. '</td>
  41.  
  42. </tr>';
  43.  
  44. }
  45. echo'</table>';
  46.  
  47. mysqli_free_result($r);
  48.  
  49. mysqli_close($dbc);
  50.  
  51. ?>


Wynik:



DreamCatcher
Dzięki Tomal40 za odzew i poświęcony czas.

Pomyślałem, że jednak wykorzystam tę tabelę WARTOSC.

id | waluta_id | kurs| data
1 | 1 | 2.76 | 2011-04-10
2 | 2 | 4.07 | 2011-04-10
3 | 3 | 3.09 | 2011-04-10
4 | 4 | 4.66 | 2011-04-10
5 | 5 | 0.10 | 2011-04-10

Załóżmy, że te powyższe dane to stare kursy walut w tabeli.
Natomiast te poniższe, to pobrane aktualne kursy ze strony.

id | waluta_id | kurs| data
9 | 1 | 2.91 | 2011-05-02
10 | 2 | 3.85 | 2011-05-02
11 | 3 | 3.19 | 2011-05-02
12 | 4 | 4.47 | 2011-05-02
13 | 5 | 0.12 | 2011-05-02

W jaki sposób wywołać zapytanie SQL, aby wyświetlić w jednej tabelce 5 wyników, w taki oto sposób?

Lp. | Nazwa | Kod | Kurs | Data | Nowy kurs | Aktualna data | Zmiana procentowa
1. | dolar | USD | 2.76 | 2011-04-10 | 2.91 | date('Y-m-d') | %
2. | euro | EUR | 4.07 | 2011-04-10 | 3.85 | date('Y-m-d') | %
3. | frank | CHF | 3.09 | 2011-04-10 | 3.19 | date('Y-m-d') | %
4. | funt | GBP | 4.66 | 2011-04-10 | 4.47 | date('Y-m-d') | %
5. | rubel | RUB | 0.10 | 2011-04-10 | 0.12 | date('Y-m-d') | %

Co należy jeszcze uwzględnić w poniższym zapytaniu?
<code=sql>
SELECT * FROM waluta LEFT JOIN wartosc ON waluta.id=wartosc.waluta_id ORDER BY wartosc.DATA DESC LIMIT 0,10
</code>

Proszę o wyrozumiałość. Tego typu zapytania sprawiają mi kłopot.
CuteOne
Musisz wiedzieć [znaczy skrypt musi wiedzieć] które dane chcesz pobrać - znaczy, z którego dnia

9 | 1 | 2.91 | 2011-05-02 ---- 1 | 1 | 2.76 | 2011-04-10

  1. SELECT * FROM waluta LEFT JOIN wartosc ON waluta.id=wartosc.waluta_id AND DATA='2011-04-10' ORDER BY wartosc.DATA DESC LIMIT 0,10

  1. SELECT * FROM waluta LEFT JOIN wartosc ON waluta.id=wartosc.waluta_id AND DATA='2011-05-02' ORDER BY wartosc.DATA DESC LIMIT 0,10


Innymi słowy zrób dwa zapytania i połącz je wg. id waluty

DreamCatcher
To rozw. z dwoma selectami nie jest wydajne i w dodatku jest niewygodne, więc zmieniłem nieco swój skrypt PHP i doszedłem do takiej postaci:

  1. foreach ($aAmount_today as $v) {
  2. $amount_today = $v['amount'];
  3. var_dump($amount_today); // "2.91", "3.85", "3.19", "4.47", "0.12"
  4. }


  1. $query =
  2. "SELECT waluta.ID, NAZWA, KOD, wartosc.KURS AS KURS, wartosc.DATA AS DATA, $amount_today AS NOWY_KURS
  3. FROM waluta
  4. LEFT JOIN wartosc
  5. ON waluta.ID = wartosc.WALUTA_ID
  6. ORDER BY DATA DESC
  7. LIMIT 0,5";


  1. <?php
  2. if ($k['KURS'] > $k['NOWY_KURS']) $nowy_kurs = number_format(1-($k['KURS']/$k['NOWY_KURS']),2);
  3. elseif ($k['KURS'] < $k['NOWY_KURS']) $nowy_kurs = number_format($k['KURS']*100/$k['NOWY_KURS'],2);
  4. ?>
  5. <tr>
  6. <td><?php echo $k['ID']; ?></td>
  7. <td><?php echo $k['NAZWA']; ?></td>
  8. <td><?php echo $k['KOD']; ?></td>
  9. <td><?php echo $k['KURS']; ?></td>
  10. <td><?php echo $k['DATA']; ?></td>
  11. <td><?php echo $k['NOWY_KURS']; ?></td>
  12. <td><?php echo date('Y-m-d'); ?></td>
  13. <td><?php echo $nowy_kurs.' %'; ?></td>
  14. </tr>


Tabela z kursami wyświetla się, zmiany procentowe są naliczane tak, jak należy, ale... Jest problem - dla nowego kursu jest przypisana ta sama wartość (ostatnia wartość z tablicy, czyli 0.12).
Czy wrzucenie zapytania $query do pętli foreach jest jedynym rozw.?
mortus
Bo $amount_today to nie tablica.
Cytat(DreamCatcher)
Czy wrzucenie zapytania $query do pętli foreach jest jedynym rozw.?

Nie jest to żadne rozwiązanie, a tylko bardziej możesz skopać skrypt.
Moja propozycja:
  1. $query = 'SELECT w.ID, w.NAZWA, w.KOD, v.KUSR, v.DATA FROM waluta w LEFT JOIN wartosc v ON v.WALUTA_ID = w.ID';
  2. $results = mysql_query($query) or die('Błąd:<pre>'.mysql_error().'</pre>');
  3. if(mysql_num_rows($results) > 0) {
  4. while($row = mysql_fetch_assoc($results)) {
  5. $from_db[$row['KOD']] = $row;
  6. }
  7. }
  8.  
  9. $from_page = pobierz(); // tutaj pobieramy waluty ze strony
  10.  
  11. $i = 1;
  12. foreach($from_db as $code => $data) {
  13. $waluty[$i]['id'] = $data['ID'];
  14. $waluty[$i]['nazwa'] = $data['NAZWA'];
  15. $waluty[$i]['kod'] = $data['KOD'];
  16. $waluty[$i]['kurs'] = $data['KURS'];
  17. $waluty[$i]['data'] = $data['DATA'];
  18. $waluty[$i]['nowy_kurs'] = $from_page[$code]['amount'];
  19. $waluty[$i]['nowa_data'] = $from_page[$code]['date'];
  20. $waluty[$i]['zmiana'] = number_format(($from_page[$code]['amount']-$data['KURS'])/$data['KURS']*100,2);
  21. $i++;
  22. }
  23.  
  24. $output = '<table><tr><th>Id</th><th>Nazwa</th><th>Kod</th><th>Kurs</th><th>Data</th><th>Nowy kurs</th><th>Nowa data</th><th>Zmiana procentowa</th></tr>';
  25. foreach($waluty as $waluta) {
  26. $output .= '<tr>';
  27. $output .= '<td>'.$waluta['id'].'</td>';
  28. $output .= '<td>'.$waluta['nazwa'].'</td>';
  29. $output .= '<td>'.$waluta['kod'].'</td>';
  30. $output .= '<td>'.$waluta['kurs'].'</td>';
  31. $output .= '<td>'.$waluta['data'].'</td>';
  32. $output .= '<td>'.$waluta['nowy_kurs'].'</td>';
  33. $output .= '<td>'.$waluta['nowa_data'].'</td>';
  34. $output .= '<td>'.$waluta['zmiana'].'%</td>';
  35. $output .= '</tr>';
  36. }
  37. $output .= '</table>';
  38.  
  39. echo $output;


EDIT
Gdyby np. pola w tabeli w bazie danych miały angielskie nazwy, to fajnie można by było użyć funkcji array_merge().
Choć w sumie nadal można.
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-2025 Invision Power Services, Inc.