Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [MySQL] Problemy z kilkoma pytaniami
Forum PHP.pl > Forum > Bazy danych > MySQL
Spirit86
Witam, mam problem z MySQL, konkretniej z pewnymi pytaniami:
Jak zadać pytanie do Bazy danych, tak, aby zwrócone zostały 2 kolumny:
1. Ilość użytkowników
2. Ilość gości

Goście mają userid = 0
Natomiast Użytkownicy userid > 0.

Pytanie polegało by na takim czymś

  1. SELECT count(`userid`>0) AS `uzytkownicy`, count(`userid`=0) AS `goscie`
  2. FROM xn_sessions'


oczywiście nie działa...

Podanto mam problemy z pytaniami:

Cytat
WYBIERZ COS Z TABELI, GDZIE CAT = 15 ORAZ (JEŻELI POLE>0 WTEDY id=5 W  PRZECIWNYM RAZIE id=3)


Jak się pisze takie pytania?

Pozdrawiam.
nospor
Cytat
WYBIERZ COS Z TABELI, GDZIE CAT = 15 ORAZ (JEŻELI POLE>0 WTEDY id=5 W  PRZECIWNYM RAZIE id=3)

  1. SELECT cos
  2. FROM tabela WHERE CAT=15 AND ( (POLE>0 AND id=5) || (POLE<=0 AND id=3) )


Co do pierwszego to moze zaraz cos wymysle
SongoQ
Ja bym to zrobil tak:

  1. (SELECT count(*) AS ilosc, 'user'
  2. FROM tabela WHERE warunek dla uzytkownika
  3. )
  4. UNION
  5. (SELECT count(*) AS ilosc, 'gosc'
  6. FROM tabela WHERE warunek dla goscia
  7. )


To zwroci rekordy:
n | user
n | gosc

gdzie n ilosc rekordow
FiDO
Mozna tez tak:
  1. SELECT IF(userid = 0, 'Gość', 'Zalogowany') user, COUNT(*)
  2. FROM tabela GROUP BY user
nospor
Musze to napisac:
FIDO - to jest poprostu piękne Takie proste, a ja siedzialem i kombinowałem. Przyda sie na pewno.
FiDO
Jest piekne, to fakt winksmiley.jpg

Gorzej moze byc z wydajnoscia takiego rozwiazania dla wiekszych tabel. Ja mialem akurat pod reka taka z kilkoma tysiecami, wiec problemu nie bylo, ale po odpaleniu EXPLAIN zauwazylem, ze niestety index z pola userid nie jest uzywany, wiec przy wiekszej ilosci danych moze to byc gorsze niz UNION zaproponowany wyzej.
SongoQ
@FiDO sprawdzales to tylko dla MySQLa? Czy inne bazki tez?
FiDO
Tylko dla MySQL'a bo chwilowo nie mam niczego innego pod reka, ale jesli tylko RDBMS posiada tego rodzaju IF'y to mysle, ze powinno smignac bez problemu.
Moj PgSQL lezy i kwiczy, ale postaram sie sprawdzic pozniej na SQL Server 2005.

[edit]
No i sprawdzilem.. IF'a takiego tam nie ma, ale jest CASE, ktory tez dal rade.
Dla porownania umiescilem tez wersje z UNION i czasy rozlozyly sie tak: 54% dla wersji z GROUP BY i 46% dla wersji z UNION.
Spirit86
Cytat(FiDO @ 2005-12-17 20:49:55)
Dla porownania umiescilem tez wersje z UNION i czasy rozlozyly sie tak: 54% dla wersji z GROUP BY i 46% dla wersji z UNION.

Czyli które jest szybsze (% czego) ? tongue.gif
FiDO
% czasu wykonania, czyli UNION jest troszke szybsze. Przy wiekszej bazie dysproporcje moga sie zwiekszyc.
SongoQ
Jak to milo slyszec ze znowu mam racje hihihih. Ale i tak takie rzeczy wychodza po dlugich testach.
FiDO
Nie powiedzialem, ze nie masz tongue.gif

Jak tylko zobaczylem EXPLAIN'a do tego to troche zwatpilem w uzytecznosc takiego rozwiazania na wiekszych tabelach.
Swoja droga ciekawe, jak by to sie skalowalo, gdyby grup po ktorych grupujemy bylo wiecej... ciekawe czy wtedy tez metoda z UNION byla by lepsza :]

edit:
nie moglem sie powstrzymac i sprawdzilem smile.gif
Jesli chodzi o SQL Server 2005 to juz przy 3 grupach szala sie odwraca, a czym ich wiecej (testowalem do 5) tym bardziej rosna dysproporcje, tym razem na korzysc rozwiazania z GROUP BY.
MySQL jednak nie daje za wygrana i mimo teoretycznie gorszego EXPLAIN'a w wersji z UNION to rozwiazanie jest szybsze.
Jak mozesz to sprawdz jak to sie rozegra na PgSQL :]

edit2: nie chodzi mi o grupowanie po wiekszej ilosci pol, tylko z wieksza iloscia grup w takim sensie, ze np. chcemy znalezc na przykladzie tej tabeli ilosc userow z id = -1, osobno z id < 100, potem z id IN [101..130] i ostatnia grupa z id > 130 i do kazdej z tych grup ilosci.
SongoQ
Cytat
Swoja droga ciekawe, jak by to sie skalowalo, gdyby grup po ktorych grupujemy bylo wiecej... ciekawe czy wtedy tez metoda z UNION byla by lepsza :]

He he he nie bylo mowy o grupowaniu po wiekszej ilosci pol. Ale w rzeczywistosci to roznie bywa.
Spirit86
ech, mam jeszcze jedno pytanie, jak zrobić coś takiego:

Jednym pytaniem wypytuje o szczegóły rekordu o id np. 15, pobieram wiele danych z tabeli, jednakże najlepiej by było, aby do tego zapytania, dołączyć coś takiego: id_następnego_rekordu, gdzie WARUNEK, id_poprzedniego_rekordu, gdzie ten sam WARUNEK. No ewentualnie zrobić do tego drugie pytanie, tylko jak pobrać dane o id rekordu większego i mniejszego jednym pytaniem?

Próbowałem coś z LIMITEM 3, ale nie wychodziło,
co ważne, jeżeli pytanie wygląda tak:

  1. SELECT *
  2. FROM `xn_images` WHERE cat = 8 AND id= 7 LIMIT -1, 1


Chciałbym, aby jeżeli nie ma rekordu o takich Warunkach, wartość id_następnego_rekordu, bądź id_poprzedniego_rekordu równała się 0.

Pozdrawiam
SongoQ
Mozesz konkretniej na przykladach podac, jakie rekordy masz a co ma byc rezultatem.
Spirit86
Mam tabelę typu

id|cat|title...

id - auto_increment

W skrypcie pobieram dajmy na to jednym pytaniem

  1. SELECT *
  2. FROM tabela WHERE id = 5


Jednakże chcę zrobić przechodzenie między kolejnymi obrazkami w kategori, więc pobieram poprzedni rekord, a właściwie jego id, który ma taką samą kategorię oraz następny. Co ważne rekordy muszą spełniać założenie (cat musi być taka sama jak w wybranym rekordzie, np. cat = 5).

Chciałem napisać to jak najoptymalniej, tzn. zadając jak najmniej pytań do bazy danych.
Kiedyś rozwiązałem to poprzez zadanie 3 pytań
1) Pytanie o wszystkie dane rekordu
2) Pytanie o następny id (WHERE id>aktualne_id ... ORDER by id DESC)
3) Pytanie o poprzedni id (WHERE id<aktualne_id ... ORDER by id ASC)

Oczywiście jest to najmniej optymalne rozwiązanie.

A jeszcze jedno założenie, oczywiście nie mogę zrobić czegoś takiego: poprzednie_id = aktualne-1; i analogicznie nastepne_id - z wiadomych przyczyn.
SongoQ
Mozna w ten sposob ale wymogiem jest aby bo kolejne rekordy i poprzednie istnialy.

  1. SELECT id, (id + 1) AS n, (id - 1) AS p
  2. FROM tabela .............
Spirit86
a jak nie będą istniały, ktoś je skasował, albo są przypisane do innej kategorii, wtedy już nie będzie działać.
SongoQ
Mozesz uzyc podzapytania i numerowac rekordy, tylko nie wiem czy MySQL ma takie cos.
Spirit86
wiesz, jakoś nie za bardzo zrozumiałem Twój algorytm, jak ja mam takie coś zrobić w MySQL smile.gif?
Widuję czasami w galeriach napisanych w php takie przechodzenie między kolejnymi obrazkami w galerii. Jak wyżej pisałem, zawsze używałem 2 odrębnych pytań, no ale, to jest nieoptymalne.
Pozdro
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.