Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

 
Reply to this topicStart new topic
> Jak napisać zapytanie, dot. 2 tabel
SamoChwała
post 25.09.2004, 15:07:39
Post #1





Grupa: Zarejestrowani
Postów: 44
Pomógł: 0
Dołączył: 28.07.2004
Skąd: Łódź

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


Nie wiedziałem za bardzo jaki dać tytuł, a chodzi mi o zapytanie, które spełniło by następujący warunek.

Zakładając, że prowadze księgarnie i mam w Tab1 skatalogowane ksiązki. W Tab2 rejestruję datę wyporzyczenia. Teraz chcę otrzymać w wyniku wszystkie książki które nie zostały wpożyczone w zadanym okresie czasu.

Kombinowałem tak (w tym przykładzie są akurat wstawione daty, normalnie są zczytywane z pola "input".

  1. SELECT
  2. `Tab1`.`idKsiazki`,
  3. `Tab1`.`tytul`,
  4. `Tab1`.`dzial`,
  5. `Tab2`.`data`
  6. FROM `Tab1` LEFT OUTER JOIN `Tab2` ON (`Tab1`.`idKsiazki` = `Tab2`.`idKsiazki`)
  7. WHERE (`Tab1`.`dzial` = 8) AND (`Tab2`.`data` BETWEEN '2004-01-01' AND '2004-03-15')


Próbowałem też bez "LEFT OUTER JOIN " na samych warunkach "Tab1.idKsiazki<>Tab2.idKsiazki" i też lipa.

Może ktoś pomóc?


--------------------
Pozdrawiam, SamoChwała
Go to the top of the page
+Quote Post
cim
post 25.09.2004, 15:33:45
Post #2





Grupa: Zarejestrowani
Postów: 208
Pomógł: 28
Dołączył: 9.08.2004
Skąd: Stargard

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


  1. SELECT Tab1.idksiazki, Tab1.tytul, Tab1.dzial, Tab2.DATA FROM Tab1, Tab2 WHERE (Tab1.idKsiazki = Tab2.idKsiazki) AND (Tab1.dzial = 8) AND (Tab2.DATA BETWEEN '2004-01-01' AND '2004-03-15')

:?:


--------------------
errare humanum est
Go to the top of the page
+Quote Post
popbart
post 25.09.2004, 16:06:49
Post #3





Grupa: Zarejestrowani
Postów: 255
Pomógł: 0
Dołączył: 22.04.2004
Skąd: Żoliborz

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


To powinno wyświetlić wszystkie książki nie wypożyczone
  1. SELECT Tab1.idksiazki, Tab1.tytul, Tab1.dzial
  2. FROM Tab1 LEFT JOIN Tab2 ON Tab1.idksiazki=Tab2.idksiazki
  3. WHERE Tab2.idKsiazki IS NULL
  4. GROUP BY Tab1.idksiazki
  5. ORDER BY Tab1.tytul

cool.gif

Ten post edytował popbart 25.09.2004, 16:09:56


--------------------
Visual Basic - kto by pomyślał :)
Go to the top of the page
+Quote Post
SamoChwała
post 26.09.2004, 17:25:53
Post #4





Grupa: Zarejestrowani
Postów: 44
Pomógł: 0
Dołączył: 28.07.2004
Skąd: Łódź

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


  1. SELECT Tab1.idksiazki, Tab1.tytul, Tab1.dzial, Tab2.DATA FROM Tab1, Tab2 WHERE (Tab1.idKsiazki = Tab2.idKsiazki) AND (Tab1.dzial = 8) AND (Tab2.DATA BETWEEN '2004-01-01' AND '2004-03-15')

Takie zapytanie nie wyświetla żadnego rekordu, jusz to przerabiałem w róznych wariantach i z różnymi warunkami.

  1. SELECT Tab1.idksiazki, Tab1.tytul, Tab1.dzial
  2. FROM Tab1 LEFT JOIN Tab2 ON Tab1.idksiazki=Tab2.idksiazki
  3. WHERE Tab2.idKsiazki IS NULL
  4. GROUP BY Tab1.idksiazki
  5. ORDER BY Tab1.tytul



To wszystko jest OK! jeśli mają być pokazane wszystkie książki które jeszcze nie zostały wypożyczone. Do takich samych wyników doszedłem chociaż odrobinę inaczej skonstruowane było(y) pytania.

Problemem jest wylistowanie książek, które nie były wypożyczone np. w 1 kwartale tego roku. Od konkretnej daty do konkretnej daty.

Ten post edytował SamoChwała 26.09.2004, 17:29:40


--------------------
Pozdrawiam, SamoChwała
Go to the top of the page
+Quote Post
rogrog
post 26.09.2004, 18:03:02
Post #5





Grupa: Zarejestrowani
Postów: 602
Pomógł: 1
Dołączył: 3.04.2004
Skąd: Trójmiasto (Gdańsk)

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


  1. ... HAVING DATA BETWEEN '2004-01-01' AND '2004-03-15'


--------------------
Go to the top of the page
+Quote Post
SamoChwała
post 26.09.2004, 18:39:38
Post #6





Grupa: Zarejestrowani
Postów: 44
Pomógł: 0
Dołączył: 28.07.2004
Skąd: Łódź

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


To też już testowałem, efekt taki sam. Wyświetla ZERO rekordów.

Coś czytałem o tabelach wirtualnych (tymczasowych) tylko nie jestem pewien czy to dotyczyło akurat MySQL. Wtedy chyba było by łatwo zastosować to 1 zapytanie do wirtualnej tabeli w której były by tylko rekordy z zadanego okresu.

Dobrze kombinuje? Czy może jest inne rozwiązanie?


--------------------
Pozdrawiam, SamoChwała
Go to the top of the page
+Quote Post
peyn
post 27.09.2004, 11:33:22
Post #7





Grupa: Zarejestrowani
Postów: 11
Pomógł: 0
Dołączył: 20.09.2004
Skąd: Konin

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


Hmm, zdaje mi sie ze jednym zapytaniem tego w mySQLu nie da sie zrobic jako ze nie ma tutaj zapytan zagniezdzonych. Gdyby byly zrobilbym to tak:

  1. SELECT a.* FROM Tab1 a WHERE a.idksiazki NOT IN (SELECT b.idksiazki FROM Tab2 b WHERE (b.DATA BETWEEN '2004-01-01' AND '2004-03-15') ORDER BY b.DATA) ORDER BY a.idksiazki;


No ale skoro nie ma to zakladajac ze robisz to w php zrobilbym to tak :-)

  1. <?php
  2.  
  3. $z = &#092;"SELECT idksiazki FROM Tab2 WHERE (data BETWEEN '2004-01-01' AND '2004-03-15') ORDER BY data\";
  4. $w = mysql_query($z);
  5. while($r = mysql_fetch_array($w))
  6. {
  7. if($id=='')
  8. {
  9.  $id=$r['idksiazki'];
  10. }
  11. else
  12. {
  13. $id.=','.$r['idksiazki'];
  14. };
  15. }
  16.  
  17. //a teraz juz tylko pobranie ksiazek i ich wyswietlenie
  18. $z = &#092;"SELECT idksiazki FROM Tab1 WHERE idksiazki NOT IN (\".$id.\")\";
  19. $w = mysql_query($z);
  20. while($r = mysql_fetch_array($w))
  21.  
  22.  
  23. ?>


Tak bym to zrobil ale jak jest jakis prostrzy sposob to dajcie znac.
Go to the top of the page
+Quote Post
SamoChwała
post 27.09.2004, 18:51:45
Post #8





Grupa: Zarejestrowani
Postów: 44
Pomógł: 0
Dołączył: 28.07.2004
Skąd: Łódź

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


peyn jesteś wielki!!! Dzięki w imieniu kolegi - TO DZIAŁA!

Fak, MySQL ma jednak kilka wad w odróżnieniu od SQL. M.in. brak możliwości konstruowania podzapytań, a to boli. Podobnie jak brak UNION.
Chodzą słuchy, że od wersji 5 te niedogodności mają być usunięte. Przynajmniej UNION ma być (już nawet w wersji beta jest - czytałem).

Rozwiązałem ten problem podobnie, ale tworząc jako pierwszą tabelę tymczasową:
  1. CREATE TEMPORARY TABLE Tab2_kopia
  2. SELECT idKsiazki, Tytul, dataWyp
  3. FROM Tab2 WHERE DATA BETWEEN '2004-01-01' AND '2004-03-15'


Działa również prawie poprawnie. Prawie dlatego, że nie pozwala wybrać ponownego zakresu dat (zczytywane z pol INPUT). Po pierwszym odpaleniu jest OK, a przy ponownym wywala błąd. Muszę jeszcze posiedzieć nad zwolnieniem pamięci. Standardowe zamknięcie tabeli nie pomaga (lub z moim kompem tzn. serwerm coś nie tak).

Reasumując Twoje rozwiązanie jest znacznie szybsze i nie obciąża zbędnie pamięci.

Jeszcze raz dziękuje.


--------------------
Pozdrawiam, SamoChwała
Go to the top of the page
+Quote Post
peyn
post 27.09.2004, 19:03:53
Post #9





Grupa: Zarejestrowani
Postów: 11
Pomógł: 0
Dołączył: 20.09.2004
Skąd: Konin

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


Co do UNION w mySQLu to jest pewien trick (nie do konca go pamietam a wale z glowy wiec moge walnac jakiegos byczka)

Zalozmy ze chcemy polaczyc 2 tabele (tab1, tab2). Tworzymy do tego celu trzecia tabele - powiedzmy tmp. W tej trzeciel tabeli tworzymy 1 kolumne i do niej wpisujemy 2 rekordy (np: 1,2) Gdybysmy chcieli polaczyc 3 tabele to wstawiamy 3 rekordy, 4 to 4, itd.

Teraz wystarczy juz tylko zrobic takie zapytanie zeby polaczyc JOINem tab1 z tmp na podstawie pola gdzie wartosc=1 a tab2 z tmp na podstawie pola gdzie wartosc=2.

Wtedy otrzymujemy mniej wiecej cos takiego

--------------------------------
1 | Wartosc z Tab1
2 | Wartosc z Tab2
2 | Wartosc z Tab2
1 | Wartosc z Tab1

Czyli mamy jakby takiego UNIONa

biggrin.gif
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.07.2025 - 09:46