Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [MySQL 4.*] Bardziej zaawansowane pytanie
Forum PHP.pl > Forum > Bazy danych > MySQL
Spirit86
Witam, mam 2 tabelę :
1) xn_users
2) xn_ranks

Teraz chcę otrzymać takie coś:

Wybierz (POLA) z tabel xn_users, xn_ranks, takie, że xn_ranks.
->pole xn_user.id równe jest 5
ORAZ
->Jeżeli xn_users.rank_id>0 Pobierz xn_ranks.id=xn_users.rank_id
W Przeciwnym Razie pobierz taką wartość, że rank_min>xn_users.points (pierwsza wartość, która jest większa równa od wymaganej ilości punktów)

Napisałem pytanie do bazy:

  1. SELECT nick, level, sign, from_, sex, avatar, gg, www, points, xn_ranks.rank_name
  2. FROM `xn_users`, `xn_ranks`
  3.  
  4. WHERE xn_users.id='5' AND (
  5. IF(xn_users.rank_id>0 ){
  6. xn_ranks.id = xn_users.rank_id
  7. }
  8. ELSE{
  9. xn_ranks.rank_min>xn_users.points
  10. }
  11. ) LIMIT 1


Niestety, jak się domyślacie nie działa sad.gif.
Pozdrawiam
orson
witam ...

zwraca błąd questionmark.gif if nie może występować w where ...
rozbij to na logiczne zdanie ( tylko OR XOR i AND) ...
jakoś tak (totalnie z palca ale taka zasada jest ...
  1. WHERE xn_users.id='5' AND (
  2. (xn_users.rank_id>0 AND xn_ranks.id = xn_users.rank_id)
  3. XOR
  4. (xn_users.rank_id < 0 AND xn_ranks.rank_min>xn_users.points))

na pewno musisz przerobić

pozdrawiam
Synaps
  1. SELECT nick, level, sign, from_, sex, avatar, gg, www, points, xn_ranks.rank_name
  2. FROM `xn_users`, `xn_ranks`
  3. WHERE xn_users.id='5' AND xn_users.rank_id > 0 AND xn_ranks.id = xn_users.rank_id
  4. UNION ALL
  5. SELECT nick, level, sign, from_, sex, avatar, gg, www, points, xn_ranks.rank_name
  6. FROM `xn_users`, `xn_ranks`
  7. WHERE xn_users.id='5' AND xn_users.rank_id<=0 AND xn_ranks.rank_min > xn_users.points


na szybko, ale powinno działać, chyba że nie zrozumiałem do końca tego co chciałeś osiągnąć.
Spirit86
niestety nie działa, tzn. jak użytkownik ma więcej punktów, niż najwyższe ranga , wtedy zapytanie nie zwraca ŻADNEGO rezultatu, a ja chciałbym, żeby zwracało wszystko, a pole rank_name dało puste.
Synaps
Czy dla innych przypadków zwraca Ci poprawne dane questionmark.gif? Z tego co zroumiałem w kwesti pkt. usera to chyba potrzebna Ci obsługa trzeciego warunku. Możesz dodać koleją unie, która by ten warunek obsługiwała. Ciekawi mnie jeszcze jak wyglada sprawa z wydajnością.
Spirit86
ech, tylko problem w tym, że to ma być przyjazne dla serwera, czyli pytania mają go obciążać w jak najmniejszym stopniu, tu liczy się każdy milisekunda (jak w reklamie MobilOne tongue.gif). Z resztą, z tego co zauważyłem działa poprawnie, no ale czas wykonywania pytania: 0.012 to chyba z deczka duży, szczególnie, jak jest więcej danych.
Synaps
Jak najbardziej się zgodze. Jednak to zapytanie wcale takie obciążające nie jest, mógłbyś spróbowac dodac indeks na kolumnie rang_id w tabeli z userami, moglo by to przyspieszyc sprawe, jesli rzeczywiscie jest on az tak wolna.
Spirit86
hehe. a zmodyfikował byś to pytanie, tak, aby działało ? Nie mam bladego pojęcia na czym polega union, a potrzebuję tego pytania najszybciej jak się da:).
Pozdrawiam
dr_bonzo
Praktyczna rada: czekasz po kilka godzin na odpowiedz -- w tym samym czasie zdazyl bys poznac UNIONa smile.gif
Spirit86
Cytat(dr_bonzo @ 2005-11-08 21:11:18)
Praktyczna rada: czekasz po kilka godzin na odpowiedz -- w tym samym czasie zdazyl bys poznac UNIONa smile.gif

w międzyczasie robię rysunek techniczny tongue.gif
Synaps
UNION pozwala ci łączyc wyniki kilku zapytań. Aby można było łączyc poszczególne zapytania, musi zby spełniony warunek : ilosc i typy pól w sekcji select musi byc identyczna we wszystkich zapytania laczonych unią. Proste i szybkie.
Co do Twojego przypadku to kwestia rozchodzi się o stworznie dodatkowego zapytania, które obsługuje kolejna grupe rekordow
( gdzie punktacja > rangi ). Jesli sobie nie poradzisz to może jutro jak bede mial chwile to wrzuce ta 3 unie. btw: dodales indeks, pomoglo questionmark.gif?
Spirit86
ech, zauważyłem, że jeśli uzytkownik ma 0 punktów, wtedy Zwraza wiele rekordów.
ykonanie zapytania trwało 0.0190 sekund

Dzięki za wytłumaczenie zasady działania Union. Wiesz, zastanawiam się, czy nie dało by się użyć czegoś a'la Switch w php. Tzn., coś podobnego do:

  1. SELECT nick, level, sign, from_, sex, avatar, gg, www, points, xn_ranks.rank_name
  2. FROM `xn_users`, `xn_ranks`
  3. WHERE xn_users.id='5' AND (SWITCH(xn_users.rank_id) {
  4. case >0:
  5. xn_ranks.id = xn_users.rank_id
  6. DEFAULT:
  7. xn_users.points >=`rank_min`
  8. }

tylko nie mogę doszukać się w manualu switcha, ech kiepsko z tym moim angielskim
FiDO
Szukaj pod haslem CASE.. jest cos takiego w MySQL'u. Po przyklady mozesz zajrzec do przyklejonego topicu w tym dziale.
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.