Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

 
Reply to this topicStart new topic
> [SQL] where i funkcja max
peter13135
post 11.12.2009, 17:06:37
Post #1





Grupa: Zarejestrowani
Postów: 1 447
Pomógł: 191
Dołączył: 26.03.2008

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


  1. SELECT f. * , t.name AS lt_name, t.id AS lt_id
  2. FROM `laczekbb_forums` f
  3. LEFT JOIN `laczekbb_topics` t ON f.id = t.forum
  4. WHERE t.id = max( t.id )
  5. GROUP BY f.id ASC
  6. ORDER BY f.cat ASC , f.id ASC


omówienie zapytania:
zapytanie ma za zadanie pobierać fora oraz ostatni temat w danym forum
tabela `laczekbb_forums` to poprostu fora/kategorie forum
tabela `laczekbb_topics` to tematy które są uporządkowane w tych kategoriach
t.forum - to id forum w jakim znajduje się temat

problem polega na tym że po dodaniu
  1. WHERE t.id = max( t.id )

zapytanie nie działa,

w jaki sposob mogę osiągnąć to że do tych for "doklejany" jest temat o najwyższym id w danej kategorii ?

czyli jeśli mam 3 tematy w konkretnym forum, i mają kolejo id 1,43,678 to żeby mi wybrało ten z id 678. Dodam że dodanie Order by t.id DESC nie pomoga


PS. no właściwie to wolałbym po dacie a nie po id, ale to już sobie poradzę żeby to przerobić


--------------------
:)
Go to the top of the page
+Quote Post
jacusek
post 11.12.2009, 18:42:34
Post #2





Grupa: Zarejestrowani
Postów: 262
Pomógł: 3
Dołączył: 18.10.2009
Skąd: Łódź

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


Nie wiem czy to coś pomoże, ale może spróbuj dodać coś takiego:
  1. WHERE t.id = select max( t.id ) from twoja_tablica

Mnie kiedyś coś takiego pomogło.

Ten post edytował jacusek 11.12.2009, 18:47:32
Go to the top of the page
+Quote Post
blooregard
post 11.12.2009, 20:50:00
Post #3


Newsman


Grupa: Moderatorzy
Postów: 2 033
Pomógł: 290
Dołączył: 21.12.2007
Skąd: Łódź




Cytat
Nie wiem czy to coś pomoże, ale może spróbuj dodać coś takiego:

Pomoże. To są tzw. podzapytania. Tylko pamiętaj o zapisaniu go w nawiasach:
  1. WHERE t.id = (SELECT max( t.id ) FROM twoja_tablica)


Poza tym podzapytania sa bardzo obciążającą wydajnościowo konstrukcją SQL-a. Jeśli możesz, postaraj się najpierw zwykłym SELECT-em wyciągnąć ten max(t.id), a potem wstawić go do właściwego zapytania jako zmienną.


--------------------
Life's simple... You make choices and don't look back...
Go to the top of the page
+Quote Post
peter13135
post 11.12.2009, 22:06:01
Post #4





Grupa: Zarejestrowani
Postów: 1 447
Pomógł: 191
Dołączył: 26.03.2008

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


max(t.id) jest inny dla kazdego forum, wiec chyba to nie bedzie takie proste... czy niema innego sposobu questionmark.gif wydaje mi sie ze to prosta sprawa, moze cos z sortowaniem ?


--------------------
:)
Go to the top of the page
+Quote Post
thomson89
post 11.12.2009, 22:43:42
Post #5





Grupa: Zarejestrowani
Postów: 1 178
Pomógł: 51
Dołączył: 7.01.2009
Skąd: Gdańsk

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


jezeli każde id jest 'następne po sobie', sortujesz odwrotnie i pobierasz id pierwszego wiersza

Ten post edytował thomson89 11.12.2009, 22:43:50


--------------------
Sklep 70%
Go to the top of the page
+Quote Post
bolverk
post 11.12.2009, 23:40:58
Post #6





Grupa: Zarejestrowani
Postów: 57
Pomógł: 6
Dołączył: 10.08.2009
Skąd: Nowe Miasto Lubawskie

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


Kod
SELECT f. * , t.name AS lt_name, t.id AS lt_id
FROM `laczekbb_forums` f
LEFT JOIN `laczekbb_topics` t ON f.id = t.forum
WHERE t.id = max( t.id )
GROUP BY f.id ASC
ORDER BY f.cat ASC , f.id ASC


Dla mnie w tym zapytaniu zwróciło uwagę odwoływanie się do aliasów. Zazwyczaj odwoływanie się do aliasów następuje po wyrażeniu FROM, np:
Kod
select c1.name, c2.name, c1.city
from customers as c1, customers as c2
where c1.city = c2.city


A w Twoim zapytaniu odwołanie do aliasów następuje przed wyrażeniem FROM. Można by mnie osądzić o małą wiedzę na temat składni SQL, ale czy aliasy nie powinny być po wyrażeniu FROM? Jeśli nie mam racji to proszę o poprawienie mnie smile.gif


--------------------
Użytkownicy jak życie, wszystkim mogą cię zaskoczyć.
Go to the top of the page
+Quote Post
peter13135
post 12.12.2009, 10:34:30
Post #7





Grupa: Zarejestrowani
Postów: 1 447
Pomógł: 191
Dołączył: 26.03.2008

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


bolverk - przykro mi ale cię kompletnie nie rozumiem

thomson89 niewiem czy masz racje bo tak średnio cię rozumiem, masz na myśli żeby pobrać najpierw to maxymalne id i potem je wstawić do zapytania questionmark.gif jeśli tak, to proszę pokaż mi jak to zrobić. Problem polega na tym że do każdy temat jest w jakimś konkretnym forum, dla każdego forum temat o maxymalnym id jest inny. dla przykładu dla forum 1 są tematy o id 1,3,8, a dla forum 2 są tematy o id 2,4,5, dla dla forum 3 są tematy o id 6,7,9
więc :
forum - ostatni id temat
1 - 8
2 - 5
3 - 9


chyba nie możliwe jest wyciągnięcie tego id wcześniej i wstawienie do zapytania, chyba że macie coś na myśli czego ja nie rozumiem

EDIT://

SELECT f. * , t.name AS lt_name, t.id AS lt_id
FROM `laczekbb_forums` f
LEFT JOIN `laczekbb_topics` t ON f.id = t.forum
WHERE t.id = (
SELECT max( id )
FROM `laczekbb_topics`
WHERE forum = f.id )
GROUP BY f.id ASC

zrobiłem tak, i jakoś działa, troche wolniej, więc nie wiem jak to będzie działało przy większej liczy rekordów, ale póki co to najlepsze rozwiązaenie jakie znam

Ten post edytował peter13135 12.12.2009, 10:43:48


--------------------
:)
Go to the top of the page
+Quote Post
thek
post 12.12.2009, 11:09:13
Post #8





Grupa: Moderatorzy
Postów: 4 362
Pomógł: 714
Dołączył: 12.02.2009
Skąd: Jak się położę tak leżę :D




A czemu nikt nie pomyślał o właściwym order by? winksmiley.jpg Skoro łączymy fora i tematy to tam już musimy przesłać tematy uporządkowane od najwyższego i dopiero grupować po id_forum. To sprawi, że dostaniemy tę strukturę o jaką chodzi... W najprostszej postaci jaką opisałem (niekoniecznie optymalnej) to byłoby:
  1. SELECT * FROM (SELECT f.id AS forum, t.id AS topic FROM forums f LEFT JOIN topics t ON f.id = t.forum ORDER BY f.id ASC, t.id DESC) GROUP BY forum
Czy coś w tym stylu smile.gif Piszę z palca bo nie mam serwera MysQL na kompie dziewczyny zainstalowanego. Jedyny byk jaki może wyniknąć to taki, że całe to za FROM podzapytanie zwróci error, iż brak mu aliasu smile.gif Wtedy tylko minimalna zmiana i powinno hulać.

EDIT: Ja wyciągnąłem jedynie id forum i id tematu najwyższego. Ty możesz dopisać więcej kolumn.

Ten post edytował thek 12.12.2009, 11:10:02


--------------------
Najpierw był manual... Jeśli tam nie zawarto słów mądrości to zapytaj wszechwiedzącego Google zadając mu własciwe pytania. A jeśli i on milczy to Twój problem nie istnieje :D
Go to the top of the page
+Quote Post
peter13135
post 12.12.2009, 18:34:54
Post #9





Grupa: Zarejestrowani
Postów: 1 447
Pomógł: 191
Dołączył: 26.03.2008

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


  1. SELECT f. * , t.name AS lt_name, t.id AS lt_id
  2. FROM `laczekbb_forums` f
  3. LEFT JOIN `laczekbb_topics` t ON f.id = t.forum
  4. WHERE t.id = (
  5. SELECT max( id )
  6. FROM `laczekbb_topics`
  7. WHERE forum = f.id )
  8. GROUP BY f.id ASC


jak wcześniej pisałem takie coś działa... ale tylko wtedy kiedy w forum istnieje temat, jeśli w danym forum niema ani jednego tematu to poprostu nie zwróci rekordu, co trzeba zrobić aby w przypadku braku tematów w forum pola pola lt_id oraz lt_name były poprostu zwracane jako puste ?

PS. w tabeli forums znajduje się kolumna o nazwie `topics` której zawartość to liczba tematów, może się to przyda

napisałem tak

  1. SELECT f. * , t.name AS lt_name, t.id AS lt_id
  2. FROM `laczekbb_forums` f
  3. LEFT JOIN `laczekbb_topics` t ON t.id = (
  4. SELECT max( id )
  5. FROM laczekbb_topics
  6. WHERE forum = f.id )
  7. GROUP BY f.id


i wydaje sie działać poprawnie

Ten post edytował peter13135 12.12.2009, 17:46:54


--------------------
:)
Go to the top of the page
+Quote Post
thek
post 12.12.2009, 20:26:28
Post #10





Grupa: Moderatorzy
Postów: 4 362
Pomógł: 714
Dołączył: 12.02.2009
Skąd: Jak się położę tak leżę :D




Widzę, że nawet nie sprawdziłeś czy zapytanie jakie Ci podałem działa! Dorwałem się do swojego kompa i założyłem 2 tabele:
FORUM
id nazwa
1 Pierwsze
2 Drugie
3 Trzecie
4 Czwarte

TOPIC
id forum_id nazwa
1 1 Jeden
2 1 Dwa
3 1 Trzy
4 3 Cztery
5 3 Pięć
6 3 Sześć
7 4 Siedem
8 4 Osiem

Zauważ, że forum o id = 2 nie ma topiców żadnych... Teraz zapytanie:
  1. SELECT * FROM (SELECT f.id AS forum, f.nazwa AS nazwa_forum, t.id AS topic_id FROM forum f LEFT JOIN topic t ON f.id = t.forum_id ORDER BY f.id ASC, t.id DESC) a GROUP BY a.forum

i w efekcie dostałem...
forum nazwa_forum topic_id
1 Pierwsze 3
2 Drugie NULL
3 Trzecie 6
4 Czwarte 8
Czy było to tak trudno sprawdzić?

Co lepsze... Minimalna zmiana i nawet LEFT JOIN wystarczył:
  1. SELECT f.id AS forum, f.nazwa AS nazwa_forum, max(t.id) AS topic_id FROM forum f LEFT JOIN topic t ON f.id = t.forum_id GROUP BY f.id


EDIT: Twoje selecty i join zostały skrócone do jednego LEFT JOIN i grupowania smile.gif Wystarczy teraz jedynie sprawdzać, czy topic_id jest równe NULL. Jeśli tak to znaczy, że forum nie posiada tematów.

EDIT2: Zerknąłem na stronę MySQL.... Tam przykład z LEFT JOIN jest nawet w przykładach sciana.gif
http://dev.mysql.com/doc/refman/5.1/en/exa...lumn-group.html

Ten post edytował thek 12.12.2009, 20:36:38


--------------------
Najpierw był manual... Jeśli tam nie zawarto słów mądrości to zapytaj wszechwiedzącego Google zadając mu własciwe pytania. A jeśli i on milczy to Twój problem nie istnieje :D
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: 12.07.2025 - 17:23