Mam sobie kod:
<?php
$conn = mysql_connect("xxx","xxx","xxx");
mysql_select_db("xxx");
if (mysql_errno()) {
echo mysql_error() . ": " . mysql_errno() . "<br>n";
exit;
}
$query = "SELECT user FROM matryca group by user";
$result = mysql_query($query) or die(mysql_error());
$num_rows = mysql_num_rows($result);
for ($i=0; $i<$num_rows; $i++) {
$wiersz = mysql_fetch_array($result);
echo "<br />";
echo "<td>".$wiersz["user"]."</td>";
echo "</td>";
}
$query = "SELECT usersl, logi, badi, inne FROM Dane order by usersl";
$result = mysql_query($query) or die(mysql_error());
$num_rows = mysql_num_rows($result);
for ($i=0; $i<$num_rows; $i++) {
$wiersz = mysql_fetch_array($result);
echo "<td>".$wiersz["usersl"]."</td>";
echo "</td>";
}
?>
Chciałbym w jakiś sposób porównać wynik z query 1 tak aby do każdego unikalnego "User" odnalazł pasujące dane z query 2 i wyświetlił dane w postaci identycznych rekordów. Czyli dla User z bazy 1 znalazłem "jakieś" rekordy które zawierają sie w query 2 dla dla User z query 1. Podobne rozwiązanie zrobiłem MYSQL ale interesuje mnie rozwiązanie w PHP.
Kompletnie nie wiem jak się za to zabrać Męczyłem się już array, array_diff a może wystarczy zwykłe if ? Pomoże ktoś?
Dzięki
zacznij od zapoznania się z: http://www.php.net/manual/en/ref.array.php
w tych funkcjach na pewno znajdziesz coś dla siebie.
W zależności od struktury danych jedynie inaczej byś na pętlach używał wyszukiwania elementów w drugiej tablicy.
W najwyższej pętli byś wybierał klucz wyszukiwania. Potem używał szukajki w drugiej tablicy i zwracał pewne wyniki, które obrabiałbyś. Potem kolejny klucz szukania i tak w kółko...
EDIT: Tutaj miałbyś szukanie po user z query1 i wpisy w query2 dla kolumny usersl zwykłym porównaniem
No chyba, że znasz dokładnie klucz nazwy usera szukanego to najbardziej zewnętrzny foreach leci i tylko wewnętrzny jest w użyciu. Oczywiście najszybsza implementacja polega na optymalizacji. Jakiej? Userowie w $query1 są różni a tabela $query 2 w każdym przebiegu nie tylko szuka ale w przypadku znalezienia pasującego rekordu, po wypisaniu danych na ekran czy do jakiegokolwiek strumienia, usuwa go Każdy więc przebieg pętli daje nam szansę na skrócenie kolejnych.
foreach( $query1 AS $user ) { foreach( $query2 AS $logs) { if($user['user'] == $logs['usersl']) { //róbta co chceta } } }
[font="Times New Roman"][size="3"] Thek,
doradź jeszcze proszę jak to osadzić w kodzie.. Rozumiem, że w pierwszej pętli robię klucz:
Może tutaj jakoś już łatwo z arraya porównywać ? Tylko problem w tym, że nie mogę dojść jak.. in_array myślę, że będzie najbardziej odpowiednie tylko jak.. Foreach'em też zapewne się da..
Blokada zaczyna mi się na samym początku.. if(....
Dzięki za wszelkie porady.
To zerknij sobie na spokojnie i pomyśl gdzie robisz porównanie Masz w tej chwili dwie dwuwymiarowe tablice. Pierwsza z nich jest postaci:
http://www.php.net/array( [0] => http://www.php.net/array([0] => 'user1'), [1] => http://www.php.net/array([0]=> 'user2'), [2] => http://www.php.net/array([0]=> 'user3') );
http://www.php.net/array( [0] => http://www.php.net/array([0] => 'usersl1', [1] => 'logi1', [2] => 'badi1', [3]=> 'inne1'), [1] => http://www.php.net/array([0] => 'usersl2', [1] => 'logi2', [2] => 'badi2', [3]=> 'inne2'), [2] => http://www.php.net/array([0] => 'usersl3', [1] => 'logi3', [2] => 'badi3', [3]=> 'inne3') );
Możesz optymalizować poprzez wyrzucanie potem odpowiedniego klucza z drugiej tablicy. Sprawi to fajną rzecz bo zmniejsza ową tablicę z danymi i gdy pętla przeskoczy do następnego usera, to danych będzie mniej, a więc będzie mniej pustych przebiegów i mniej if-ów Z każdym krokiem pierwszej pętli foreach (czyli z kolejnymi userami) druga tablica się zmniejsza i niejako działanie przyspiesza. Możesz jeszcze ewentualnie ustawić w miejscu oznaczonym "size_checker" warunek, że jeśli wielkość $array2 będzie 0 to ma zrobić break i wyjść z foreach na amen. Wtedy pozbędziesz się być może wielu pustych przejść pętli.
foreach( $array AS $users) { //tablica userów foreach($array2 AS $key => $dane) { //tablica danych if($users[0] == $dane[0] ) { //zauważ jakie indeksy tablic porównuję w strukturze obu! //tutaj sobie coś robię z uzyskanymi danymi http://www.php.net/unset $array2[$key]; //tak usuwasz dany rekord } } //size_checker }
Dziękuję Działa ale to tylko część efektu który chcę osiągnąć więc dalej proszę o pomoc.
Teraz trochę skomplikuję.
Tabela 1 jak i Tabela 2 może mieć różną ilość rekordów. Tabelę 1 i 2 łączy ta sama nazwa "user" .
Array 1
[url="http://www.php.net/array"] http://www.php.net/array[/url]( [0] => [url="http://www.php.net/array"]http://www.php.net/array[/url]([0]=> 'user1', [1] => 'logi1', [2] => 'badi1'), [1] => [url="http://www.php.net/array"]http://www.php.net/array[/url]([0]=> 'user2', [1] => 'logi2', [2] => 'badi2'), [2] => [url="http://www.php.net/array"]http://www.php.net/array[/url]([0]=> 'user3', [1] => 'logi3', [2] => 'badi2'));
Chciałbym porównać nie tylko po "user" z query1:
http://www.php.net/array( [0] => http://www.php.net/array([0] => 'usersl1', [1] => 'logisl1', [2] => 'badisl1', [3]=> 'innesl1'), [1] => http://www.php.net/array([0] => 'usersl2', [1] => 'logisl2', [2] => 'badisl2', [3]=> 'innesl2'), [2] => http://www.php.net/array([0] => 'usersl3', [1] => 'logisl3', [2] => 'badisl3', [3]=> 'innesl3') [3] => http://www.php.net/array([0] => 'usersl3', [1] => 'logisl4', [2] => 'badisl4', [3]=> 'innesl4');
No to wtedy jedynie zmieniasz odpowiednio warunek w IF, by pasował do Twojego problemu. Nic więcej
hmm... rozważałem taką opcję ale..
W przykładzie powyżej w array1 miałem tylko jedną wartość "users"
Teraz tych wartości będzie więcej:
$array[$i] = array($wiersz["usersl"], $wiersz["levelsl"], $wiersz2["NAMEsl"]);
$array2[$j] = array($wiersz2["user"], $wiersz2["emp"], $wiersz2["level"], $wiersz2["NAME"]);
jak zrobić w takim przypadku foreach:
foreach( $array AS $users) { foreach($array2 AS $key => $dane) { if($users[0] == $dane[0] ) { http://www.php.net/echo "<tr>"; http://www.php.net/echo "<td><center>".$users[0]."</center></td>"; http://www.php.net/echo "<td><center>".$dane[1]."</center></td>"; http://www.php.net/echo "<td><center>".$dane[2]."</center></td>"; http://www.php.net/echo "<td><center>".$dane[3]."</center></td>"; http://www.php.net/echo "</tr>"; } } }
foreach( $array AS $users) { foreach($array2 AS $key => $dane) { if($users[0] == $dane[0] ) if ($user[1] == $dane[1] { itd? Definiując IFem interesujące mnie warunki? } } }
Myślisz w dobrym kierunku. Możesz to określić odrębnymi if jeśli będziesz robić z nimi różne rzeczy, lub jeśli za każdym razem to samo, to już w jednym IF stosując kwantyfikator OR:
if(user[0] == user2[0] OR user[1] == user2[1] OR ...)
Tylko w przypadku porównywania wielu opcji nie usuwaj wierszy, bo jeden może pasować do wielu.
Mój foreach:
foreach ($array as $users) { $z = $users[0]; foreach ($array2 as $key => $dane) { $a = $dane[0]; $b = $dane[1]; $c = $dane[2]; $d = $dane[3]; foreach ($array3 as $key2 =>$dane2) { $e = $dane2[0]; $f = $dane2[1]; $g = $dane2[2]; $h = $dane2[3]; }}}
To ja się pytam... Czemu zagnieżdżasz 3 foreach wewnątrz 2 zamiast umieścić 3 foreach PO 2 ? Skoro 2 foreach ma 13 rekordów, a 3 ma 1 rekord, to w wyniku masz 13 razy 1 rekord Gdyby rekordów było więcej to masz x razy y rekordów w ostatnim foreach Pomyśl zanim zaczniesz zagnieżdżać za bardzo.
Oczywiście racja, moje niedopatrzenie.
foreach ($array as $users) { $z = $users[0]; foreach ($array2 as $key => $dane) { $a = $dane[0]; $b = $dane[1]; $c = $dane[2]; $d = $dane[3]; } foreach ($array3 as $key2 =>$dane2) { $e = $dane2[0]; $f = $dane2[1]; $g = $dane2[2]; $h = $dane2[3]; } http://www.php.net/echo "<tr>"; http://www.php.net/echo "<td>".$a."</td>"; http://www.php.net/echo "<td>".$b."</td>"; http://www.php.net/echo "<td>".$c."</td>"; http://www.php.net/echo "<td>".$d."</td>"; http://www.php.net/echo "<td>".$f."</td>"; http://www.php.net/echo "<td>".$g."</td>"; http://www.php.net/echo "<td>".$h."</td>"; http://www.php.net/echo "</tr>"; }
A gdzie zgubiłeś IFy? Robiąc tak jak robisz nadpisujesz sobie zmienne od $a do $h cały czas. W sumie tak patrząc z innej perspektywy to skoro rozszerzona była tablica $users to masz nie tyle znowu ją gdzieś jeszcze raz przepychać jako trzecią, tylko sprawdzać kolejne jej wartości, każdą wartość z $users porównując z odpowiednią wartością w drugiej tablicy.
foreach( $array AS $users) { foreach($array2 AS $key => $dane) { if($users[0] == $dane[0] ) { //tu jeśli userzy Ci sami } if($users[1] == $dane[1] ) { //tu jeśli logi te same } if($users[2] == $dane[2] ) { //tu jeśli badi te same } } }
Witam
Co zrobić gdy, mają się nie zgadzać.
foreach( $array2 AS $key => $dane2 ) { foreach( $array AS $key => $dane){ if($dane[0] != $dane2[0]) { //sprawdzenie że nie ma! http://www.php.net/echo "<tr><td>".$l++."</td><td>".$dane['1']."</td><td>".$dane['2']."</td><td><b>".$dane['0']."</b></td><td>brak w bazie</td></tr>"; } } }
a sprawdź co masz w tym array i array2
Jeśli dane pochodzą z bazy, to znalezienie danych, które są w tabeli 1, a których brak w tabeli 2 i vice versa, można osiągnąć z pomocą zapytania OUTER JOIN bezpośrednio na bazie.
Jeśli silnik nie obsługuje OUTER JOIN, to: https://kawalekkodu.pl/gul-gul-na-full-czyli-o-zlaczeniu-full-outer-join-w-mysql
to są 2 oddzielne bazy. zastosowanie JOIN nic nie daje.
$idb2 = http://www.php.net/mysql_connect ($db_s2, $db_u2, $db_p2) or http://www.php.net/die ($db_error01); mysql_set_charset('utf8', $idb2); http://www.php.net/mysql_select_db ($db_d2, $idb2) or http://www.php.net/die ($db_error02); $idb1 = http://www.php.net/mysql_connect ($db_s1, $db_u1, $db_p1) or http://www.php.net/die ($db_error01); mysql_set_charset('utf8', $idb1); http://www.php.net/mysql_select_db ($db_d1, $idb1) or http://www.php.net/die ($db_error02); $num_rows = http://www.php.net/mysql_num_rows($wynik); for ($i=0; $i<$num_rows; $i++) { $wrsz = http://www.php.net/mysql_fetch_array($wynik); $array[$i] = http://www.php.net/array($wrsz['RIGHT(nr_gwarancji, 6)'], $wrsz['idmonter_id'], $wrsz['data_zmiany']); $num_rows2 = http://www.php.net/mysql_num_rows($wynik2); for ($i=0; $i<$num_rows2; $i++) { $gwar = http://www.php.net/mysql_fetch_array($wynik2); $array2[$i] = http://www.php.net/array($gwar['RIGHT(nrg, 6)'], $gwar['kod_firmy_montujacej']); } foreach( $array2 AS $key => $dane2 ) { foreach( $array AS $key => $dane){ if($dane[0] === $dane2[0]) { //to działa! http://www.php.net/echo "<tr><td>".$l++."</td><td>".$dane['1']."</td><td>".$dane['2']."</td><td><b>".$dane['0']."</b></td><td>Są w bazie</td></tr>"; } } }
if($dane[0] !== $dane2[0]) { http://www.php.net/echo "<tr><td>".$l++."</td><td>".$dane['1']."</td><td>".$dane['2']."</td><td><b>".$dane['0']."</b></td><td>Są w bazie</td></tr>"; }
1. Nie JOIN, a OUTER JOIN.
2. Możliwe jest wykonywanie zapytania łączącego tabele z dwóch oddzielnych baz.
3. W Twoim kodzie brak zapytań SQL - dane nie pojawią się znikąd.
zapytania SQl
$sSQL2 = "SELECT RIGHT(nrg, 6), `kod_firmy_montujacej` FROM `gwarancje` WHERE `dta_zapisu` BETWEEN '$data_poczg' AND '$data_zakog' GROUP BY `nrg`, `kod_firmy_montujacej` ORDER BY `gwarancje`.`dta_zapisu` DESC LIMIT $limg"; $wynik2 = http://www.php.net/mysql_query ($sSQL2, $idb2) or http://www.php.net/die ($db_error03); $sSQL1 = "SELECT RIGHT(nr_gwarancji, 6),`idmonter_id`, `data_zmiany` FROM `homologator_gwarancja` WHERE `data_zmiany` BETWEEN '$data_pocz' AND '$data_zako' GROUP BY `nr_gwarancji`, `idmonter_id` ORDER BY `homologator_gwarancja`.`data_zmiany` DESC LIMIT $limh"; $wynik = http://www.php.net/mysql_query ($sSQL1, $idb1) or http://www.php.net/die ($db_error03);
[116] => http://www.php.net/array ( [0] => 631516 [1] => 0996 [2] => 2023-01-30 05:55:35 )
[41] => http://www.php.net/array ( [0] => 633127 [1] => 0963 )
1. Nie wiem czy masz zdefiniowane $limg oraz $limh.
2. Do porównania należałoby raczej użyć array_intersect/array_diff/porównania całych tablic (==).
A jak to zapisać bo już się pogubiłem
$sSQL2 = "SELECT RIGHT(nrg, 6), `kod_firmy_montujacej` FROM `gwarancje` WHERE `dta_zapisu` BETWEEN '$data_poczg' AND '$data_zakog' GROUP BY `nrg`, `kod_firmy_montujacej` ORDER BY `gwarancje`.`dta_zapisu` DESC LIMIT $limg"; $wynik2 = http://www.php.net/mysql_query ($sSQL2, $idb2) or http://www.php.net/die ($db_error03); $sSQL1 = "SELECT RIGHT(nr_gwarancji, 6),`idmonter_id`, `data_zmiany` FROM `homologator_gwarancja` WHERE `data_zmiany` BETWEEN '$data_pocz' AND '$data_zako' GROUP BY `nr_gwarancji`, `idmonter_id` ORDER BY `homologator_gwarancja`.`data_zmiany` DESC LIMIT $limh"; $wynik = http://www.php.net/mysql_query ($sSQL1, $idb1) or http://www.php.net/die ($db_error03);
[116] => http://www.php.net/array ( [0] => 631516 [1] => 0996 [2] => 2023-01-30 05:55:35 )
[41] => http://www.php.net/array ( [0] => 633127 [1] => 0963 )
SELECT gwarancje.* FROM gwarancje RIGHT JOIN homologator_gwarancja ON gwarancje.nrg = homologator_gwarancja.nr_gwarancji WHERE gwarancje.nrg != homologator_gwarancja.nr_gwarancji
A może zapisać
foreach( $array2 AS $key => $dane2 ) { foreach( $array AS $key => $dane ) { if($dane[0] === NULL) { // pusty klucz! http://www.php.net/echo "<tr><td>".$l++."</td><td>".$dane['1']." ".$dane2['1']."</td><td>".$dane['2']."</td><td><b>".$dane['0']." ".$dane2['0']."</b></td><td>Są w bazie</td></tr>"; } } }
Opisałem Ci już rozwiązania. Można wykonać zapytanie na dwóch różnych bazach/połączeniach.
Nie JOIN, a OUTER JOIN, albo wymienione wcześniej funkcje PHP, ewentualnie pętle z in_array.
Porównywanie elementów nie ma sensu, bo nie można porównać istniejącego elementu z nieistniejącym.
Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)