Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Pętla FOR i modyfikacja pierwszego wyniku z tej pętli.
Forum PHP.pl > Forum > PHP
casperii
Witam mam kod:

  1. $where='';
  2. for($i = 0; $i < 7; $i++){
  3. if($row['numer'.$i] == '1'){
  4. $where .= ' AND `numer` = "numer'.$i.'"';
  5. }
  6. }


Jak zrobić by dla pierwszego wyniku było "AND" a dla pozostałego wyniku "OR"
Forti
Na szybkiego:

  1. $where='';
  2. for($i = 0; $i < 7; $i++){
  3. if($row['numer'.$i] == '1' && $i == 0){
  4. $where .= ' AND `numer` = "numer'.$i.'"';
  5. } elseif ($row['numer'.$i] == '1') {
  6. $where .= ' OR `numer` = "numer'.$i.'"';
  7. }
  8. }

casperii
Dziękuje za kod, ale nie działa to tak jak powinno, tzn. działa to tak jak bez tego warunku IF.
Zapytanie powinno działać na tej zasadzie, że:
-jeśli numer1='1', numer2='1', numer3='1', numer4='1', numer5='1', numer6='1' istnieje to:

  1. WHERE `nazwa`!="" AND `numer` = "numer1" OR `numer` = "numer2" OR `numer` = "numer3" OR `numer` = "numer4" OR `numer` = "numer5" OR `numer` = "numer6"


Jeżeli natomiast nie będzie numeru1 tylko od numer 2 do numer6 to zapytanie powinno być takie:

  1. WHERE `nazwa`!="" AND `numer` = "numer2" OR `numer` = "numer3" OR `numer` = "numer4" OR `numer` = "numer5" OR `numer` = "numer6"


a z twoim kodem to wygląda tak:

  1. WHERE `nazwa`!="" OR `numer` = "numer2" OR `numer` = "numer3" OR `numer` = "numer4" OR `numer` = "numer5" OR `numer` = "numer6"
Forti
  1. $where='';
  2. for($i = 0; $i < 7; $i++){
  3. if($row['numer'.$i] == '1' && $i == 1){
  4. $where .= ' AND `numer` = "numer'.$i.'"';
  5. } elseif ($row['numer'.$i] == '1') {
  6. $where .= ' OR `numer` = "numer'.$i.'"';
  7. }
  8. }


Literówkę w warunku if zrobiłem
casperii
Nic nie zmieniło dalej to wygląda tak:

  1. WHERE `nazwa`!="" OR `numer` = "numer2" OR `numer` = "numer3" OR `numer` = "numer4" OR `numer` = "numer5" OR `numer` = "numer6"


a powinno tak:

  1. WHERE `nazwa`!="" AND `numer` = "numer2" OR `numer` = "numer3" OR `numer` = "numer4" OR `numer` = "numer5" OR `numer` = "numer6"


Jeżeli nie mam w bazie zaznaczonego numer1='1', to powinno być "AND" numer='numer2',
jeżeli w bazie nie mam numer1='1' oraz numer2='1' to zapytanie powinno wyglądać tak:

  1. WHERE `nazwa`!="" AND `numer` = "numer3" OR `numer` = "numer4" OR `numer` = "numer5" OR `numer` = "numer6"
Forti
Nie ogarniam o co ci chodzi, wiesz? Pokaż co masz w bazie.


Cytat
Jeżeli nie mam w bazie zaznaczonego numer1='1', to powinno być "AND" numer='numer2',
jeżeli w bazie nie mam numer1='1' oraz numer2='1' to zapytanie powinno wyglądać tak:


masło maślane. "Jeżeli nie 1 to x, jeżeli nie 1 to y"? -,-



i nie spamuj mi na priv. Jak będę miał czas to odpiszę.
Forti
Nowy temat to niwy kod i nowy problem. Pokaz budowę bazy i jasno napisz ci chcesz zrobić.
casperii
  1. if(zalogowany()){
  2.  
  3. $nazwa = $_SESSION['nazwa'];
  4. $sql="SELECT * FROM `users` WHERE `name` = '".$nazwa."' LIMIT 1";
  5. $res=mysql_query($sql);
  6. $row=mysql_fetch_array($res,MYSQL_ASSOC);
  7. $access=$row['access'];
  8.  
  9. if($access =='m'){
  10.  
  11. $where = '';
  12. for($i = 1; $i < 7; $i++)
  13. if($row['numer'.$i] == '1'){
  14. $where .= ' OR `numer` = "numer'.$i.'"';
  15. }
  16.  
  17.  
  18. }
  19. }


W powyższym kodzie sprawdzamy czy dany user o nazwie = 'nazwa' istnieje, następnie sprawdzamy pole access w bazie jeżeli ma "m" rozpoczynamy pętle FOR.
Teraz sprawdzamy czy w polach numer1, numer2, numer3, numer4, numer5, numer6 jest wartość ="1"


Teraz w drugim pliku mam select z nazwą oraz zapytanie do bazy mysql:

  1. if(isset($zmiennaZselect)){
  2. $szukam =' WHERE `nazwa` = "'.$zmiennaZselect.'"';
  3. }else{
  4. $szukam = ' WHERE `nazwa`!="" '.$where.' ';
  5.  
  6. }
  7.  
  8. $sql = "SELECT * FROM `test` $szukam ";
  9. $res = mysql_query($sql) or die(mysql_error());
  10. if(mysql_num_rows($res)>0){
  11. while($row = mysql_fetch_assoc($res)){
  12. echo ''.$row['nazwa'].'';
  13. }
  14. }


Jeżeli wybiorę z selecta nazwę zapytanie rozszerza się o WHERE `nazwa` = "'.$zmiennaZselect.'". Jeżeli nie wybiorę nic z selecta to zapytanie będzie poprostu WHERE !=''
Następnie trzeba dodać kolejny warunek do zapytania ".$where."

Jak łatwo się domyśleć nazwa z tabeli users dla pola numer1 do numer6 może nie mieć wartość "1" wtedy nie jest brana pod uwagę w pętli FOR.
Dlatego muszę zrobić tak by dla pierwszego było "AND" a dla kolejnych było "OR"

Reasumując:

Zalogowany o nazwie GOŚĆ oraz GOŚĆ2 mają wartości w bazie:

GOŚĆ:
nazwa = 'GOSC'
access = 'm'
numer1 = '1'
numer2 = '1'
numer3 = '1'
numer4 = '0'
numer5 = '0'
numer6 = '1'

Czyli poprawne zapytanie będzie dla GOŚCiA :
  1. $sql = "SELECT * FROM `test` WHERE `nazwa` !='' AND `numer`='numer1' OR `numer`='numer2' OR `numer`='numer3' OR `numer`='numer6' ";



GOŚĆ2:
nazwa = 'GOSC2'
access = 'm'
numer1 = '0'
numer2 = '1'
numer3 = '1'
numer4 = '1'
numer5 = '0'
numer6 = '0'


Czyli poprawne zapytanie będzie dla GOŚCiA2 :
  1. $sql = "SELECT * FROM `test` WHERE `nazwa` !='' AND `numer`='numer2' OR `numer`='numer3' OR `numer`='numer4' ";


Forti
  1. for($i = 1; $i < 7; $i++) {
  2.  
  3. if($row['numer'.$i] == '1'){
  4. if ($i == 1) {
  5. $where .= ' AND `numer` = "numer' . $i . '"';
  6. } else {
  7. $where .= ' OR `numer` = "numer' . $i . '"';
  8. }
  9. }
  10. }
casperii
w dalszym ciągu jest tylko "AND" dla numer1='1' a co jeśli nie ma tego numer1='1' tylko zaczyna się od numer2='1' to od razu daje "OR" a powinno być AND.
Jeszcze raz podsumuje o co mi chodzi:
Baza mysql


nazwa access numer1 numer2 numer3 numer4 numer5 numer6
TEST m 1 1 1 1 1 1
TEST2 m 0 1 0 1 0 1
TEST3 m 0 0 1 1 0 0

teraz dla TEST powinno być:

  1. $sql = "SELECT * FROM `test` WHERE `nazwa`!='' AND `numer`='numer1' OR `numer`='numer2' OR `numer`='numer3' OR `numer`='numer4' OR `numer`='numer5' OR `numer`='numer6' ";



dla TEST2 powinno być:
  1. $sql = "SELECT * FROM `test` WHERE `nazwa`!='' AND `numer`='numer2' OR `numer`='numer4' OR `numer`='numer6' ";



dla TEST3 powinno być:
  1. $sql = "SELECT * FROM `test` WHERE `nazwa`!='' AND `numer`='numer3' OR `numer`='numer4' ";
Forti
Nic nie potrafisz sam pokombinować?

  1. $count = 0;
  2. for($i = 1; $i < 7; $i++) {
  3. $count++;
  4. if($row['numer'.$i] == '1'){
  5. if ($count == 1) {
  6. $where .= ' AND `numer` = "numer' . $i . '"';
  7. } else {
  8. $where .= ' OR `numer` = "numer' . $i . '"';
  9. }
  10. }
  11. }
  12.  
  13.  
casperii
Dalej to samo php.gif

dla TEST zrobiłem numer1="0" , numer2="0", numer3="1" , numer4="1", numer5="1", numer6="1"

wyświetla:

  1. WHERE `nazwa`!="" OR `numer` = "numer3" OR `numer` = "numer4" OR `numer` = "numer5" OR `numer` = "numer6"


gdzie dla pierwszego numeru powinno być zawsze "AND"

jak zrobię w bazie dla TEST numer1="1" , numer2="0", numer3="1" , numer4="1", numer5="1", numer6="1"

wyświetla poprawnie:

  1. WHERE `nazwa`!="" AND `numer` = "numer1" OR `numer` = "numer3" OR `numer` = "numer4" OR `numer` = "numer5" OR `numer` = "numer6"


Czyli nie ważne czy jako pierwszy będzie numer3 czy numer4 pod warunkiem że przed nim nie bedzie numer1 oraz numer2 to jako pierwszy wartość "AND" ma otrzymać numer3. Bo cały czas jest tak że jeśli istnieje numer1="1" to wtedy dodaje "AND" a nie o to mi chodzi.

Poza tym czemu print $count pokazuje mi 6 skoro np 4 numery mają wartość ="1" ?
Forti
To zmień $count = 1 i po problemie. POKOMBINUJ.

edit:

Cytat
Poza tym czemu print $count pokazuje mi 6 skoro np 4 numery mają wartość ="1" ?


Jak nie wiesz co robi $cont++ to nie mamy o czym rozmawiać.
casperii
wiem co robi ++ tzw. inkrementacja -bynajmniej tak w C++ było.

Forti nie wiem czy dobrze my się rozumiemy, co ja chcę osiągnąć.
wydaję mi się , że to powinno być na zasadzie sprawdzamy który numer jest jako pierwszy i dlatego pierwszego numeru dajemy warunek IF ... AND a kolejny OR.
Bo zmiana $count=0 na $count=1 robi tyle że nie wychwyta pierwszego numer1="1" jeśli istnieje.
Forti
Ty san źle rozumiesz co chcesz zrobić. Masz na stałe kolumny nazwa1, nazwa2 itp. więc:

  1. $fields = array('nazwa1', 'nazwa2', 'nazwa3' ...);
  2.  
  3. foreach ($fields as &$field) {
  4. if ($row[$field] == '1') {
  5. $where = ' AND `numer` = '.$field;
  6. unset($field);
  7. break;
  8. } else {
  9. unset($field);
  10. }
  11. }
  12.  
  13. foreach ($fields as $field) {
  14. if ($row[$field] == '1') {
  15. $where .= ' OR `numer` = '.$field;
  16. }
  17. }


bardzo brzydkie, nie estetyczne etc. ale twoje kolumny również są brzydkie tongue.gif

edit: nie sprawdzałem czy działa, ale powinno. Opisać Ci to czy rozumiesz?
ctom
Cytat(casperii @ 14.03.2015, 13:46:58 ) *
Witam mam kod:

  1. $where='';
  2. for($i = 0; $i < 7; $i++){
  3. if($row['numer'.$i] == '1'){
  4. $where .= ' AND `numer` = "numer'.$i.'"';
  5. }
  6. }


Jak zrobić by dla pierwszego wyniku było "AND" a dla pozostałego wyniku "OR"


chyba tak będzie łatwiej
Kod
$tmp= [];
for($i = 0; $i < 7; $i++){
    if($row['numer'.$i] == '1') array_push($tmp, 'numer' . $i);
}

$where = ' AND numer IN ('.implode(',', $tmp).')';


oczywiście dodaj gdzieś przechwycenie wyjątku gdy count($tmp) == 0
$_$
Z tego co wnioskuje to kolega chce sprawdzać wartość z bazy a nie pętli

  1. $where='';
  2. $found = false;
  3. for($i = 0; $i < 7; $i++){
  4. $condition = 'OR';
  5. if($row['number' . $i] == 1 && $found === false) {
  6. $condition = 'AND';
  7. $found = true;
  8. }
  9. $value = $row['number' . $i];
  10. $where .= $condition . ' numer'. $i .' = ' . $value;
  11. }
Forti
Cytat($_$ @ 14.03.2015, 20:19:24 ) *
Z tego co wnioskuje to kolega chce sprawdzać wartość z bazy a nie pętli

  1. $where='';
  2. for($i = 0; $i < 7; $i++){
  3. $condition = ($row['numer' . $i] == 1) ? 'AND' : 'OR';
  4. $where .= $condition . ' `numer` = ' . $i;
  5. }


To mu także nic nie da. Wydaje mi się, że skłądnia powinna być AND ? Or ? Or ? Or ? i pierwszy parametr ma być pierwsza kolumna posiadająca wartość "1", a wsześniejsze nie brane pod uwagę. Mój przykład powinien mu zadziałać.
$_$
Skoro w bazie ma int-y to nie rozumiem tego

Cytat
WHERE `nazwa`!="" AND `numer` = "numer1"
Forti
1. co oznaczaja pola numer 1 do numer 6?
2. po co jest druga tabela, co ona przedstawia?
3. Co chcesz uzyskać?

Odpowiedź dobrze na te pytania. Zwłaszcza na 3. Zakład o 1000zł, że twój problem rozwiązujesz w zły sposób.
casperii
nazwa logująca się ma przypisane numery od 1 do 6. Ale i może mieć wszystkie te numery. Jeżeli ma przypisany numer wstawiam wartość do bazy "1".
Teraz w drugiej tabeli test mam przechowane nazwy modeli o jakimś numerze z zakresu numer1 - numer6.
Wybierając z selecta tą nazwę lub jej nie wybierając (WHERE `nazwa`!='') model wyświetlam.

Porównaj to do np takiego opis.
Jeżeli Kowalski ma uprawnienie "m" i chodzi do klasy numer1, numer2, numer3,numer4,numer5,numer6. Dlatego przypisuje w bazie wartości "1" by wiedzieć do której klasy chodzi Kowalski.

Teraz w kolejnej tabeli powiedzmy, że tabela "uczniowie" chcę wyświetlić uczniów którzy chodzą do klasy 1, klasy 2 i klasy 3, albo do klasy 2 i 5.
Potem np chcę wyświetlić uczniów o nazwisku Kowalski którzy chodzą do klasy 2 i 5. Stąd tak sobie wymyśliłem.

Aha gdyby padło pytanie, dlaczego to rozbijam na 2 tabele.
W jednej tabeli przechowuje nazwę oraz hasło i te numery od 1 - 6 oraz datę logowania itp.
W drugiej tabeli już mam inne dane np data dodania, opis tego więc muszę to rozbić.
Forti
Ja nie ogarniam twojego zamiaru -,-

Masz napisać co chcesz uzyskać, a nie co masz. CEL. np.:

chce mieć użytkowników, każdy jest przypisany do jakieś klasy i w zależności od ów klasy ma jakieś tam uprawnienia.
a nie: mam tabele x, mam tabele y, chce by pole Z było G. - tak rozumiem twój opis. Może głupi jestem ;]
casperii
JA już nie wiem , czy ja po Chińsku piszę , czy ten problem jest nie do wykonania facepalmxd.gif
Nic innego nie robię jak próbuje wytłumaczyć co chcę wykonać... Baaa nawet pokazuje kod i schemat bazy mySQL.

Dobra inaczej może wytłumaczę, bo z tymi klasami to chyba jest dobry sposób.

tabela test w niej pola:
-nazwa (varchar)
-klasa1 (int)
-klasa2 (int)
-klasa3 (int)
-klasa4 (int)
-klasa5 (int)
-klasa6 (int)
-dostep (varchar)

zrzut tabeli test:
- kowalski, 1,0,1,0,1,1,nauczyciel
- nowak, 0,1,1,0,1,0,uczen
- słowik, 1,0,0,1,1,0,uczen
- ktosiek, 1,1,0,0,1,0,uczen


tabela zadania:
-nazwa,
-klasa

zrzut tabeli zadania:
-praca domowa, klasa1
-czytanie lektury,klasa3

tworzymy zapytanie do bazy $sql ... `test`

tworzymy warunek if($row['dostep']=='nauczyciel') a w nim kolejne zapytanie do tabeli zadania
$zapytanie do tabeli `zadania` tu chcę stworzyć warunek żeby wyświetliło mi tylko te zadania które wybiorę z listy select lub ich nie wybiorę ale należące do klasy do której jest przyporządkowany nauczyciel. Czyli nauczyciel ma wartość "1" dla klasy1, klasa3, klasa5, oraz klasa6. Czyli może zobaczyć wynik z tabeli zadania "praca domowa" oraz "czytanie lektury".

Jak tego nie zrozumiesz to się poddaje....
Forti
many to many - mówi Ci to coś? -,-

[user]:
- id
- nazwa
- dostęp

[zadania]:
- id
- nazwa

[user_zadania]
- id_user
- id_zadania

tobie jednak nie do końca o to chodzi, więc:

[user]
- id
- nazwa
- dostep

[klasa]
- id
- klasa

[user_klasa]
- id_user
- id_ klasa

[zadania]
- id
- nazwa
- klasa

[klasa_zadania]
- id_klasa
- id_zadania

i teraz jednym zapytaniem robisz wszystko. Left join znasz? wink.gif w necie jest tego masa. Mi się już myśleć dalej nie chce. Ale to idzie tak: pobierasz w user_klasa wszystko i LEFT JOIN user ON user_klasa.id_user = user.id LEFT JOIN ...

kurde pewnie zapytania Ci o tej godzinie nie podam, za długo z ORM korzystam biggrin.gif ale to jest najłatwiejsza droga.
casperii
Ale dlaczego rozbijasz to na 4 tabele ? :-) Nie da się stworzyć tak zapytania by pobrać wyniki z tych dwóch tabel ?

tabela test w niej pola:
-nazwa (varchar)
-klasa1 (int)
-klasa2 (int)
-klasa3 (int)
-klasa4 (int)
-klasa5 (int)
-klasa6 (int)
-dostep (varchar)

zrzut tabeli test:
- kowalski, 1,0,1,0,1,1,nauczyciel
- nowak, 0,1,1,0,1,0,uczen
- słowik, 1,0,0,1,1,0,uczen
- ktosiek, 1,1,0,0,1,0,uczen


tabela zadania:
-nazwa,
-klasa

zrzut tabeli zadania:
-praca domowa, klasa1
-czytanie lektury,klasa3

coś na styl WHERE `test`.`klasa1` = `zadania`.`klasa`

Chyba najłatwiej będzie zrobić w drugiej tabeli zadania też klasy od 1 do 6 i jeżeli należy do tej klasy to dawać wartość 1 i wtedy porównywać..
ctom
a co zrobisz gdy pojawią się klasy 1a i 1b questionmark.gif dodasz kolejne kolumny questionmark.gif

spróbuj przyswoić to co napisał Ci @Forti
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.