Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

> [SQL] where i funkcja max
peter13135
post
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
 
Start new topic
Odpowiedzi (1 - 9)
jacusek
post
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
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ą.
Go to the top of the page
+Quote Post
peter13135
post
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 (IMG:style_emoticons/default/questionmark.gif) wydaje mi sie ze to prosta sprawa, moze cos z sortowaniem ?
Go to the top of the page
+Quote Post
thomson89
post
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
Go to the top of the page
+Quote Post
bolverk
post
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 (IMG:style_emoticons/default/smile.gif)
Go to the top of the page
+Quote Post
peter13135
post
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 (IMG:style_emoticons/default/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
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? (IMG:style_emoticons/default/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 (IMG:style_emoticons/default/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 (IMG:style_emoticons/default/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
Go to the top of the page
+Quote Post
peter13135
post
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
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 (IMG:style_emoticons/default/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 (IMG:style_emoticons/default/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
Go to the top of the page
+Quote Post

Reply to this topicStart new topic
2 Użytkowników czyta ten temat (2 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Aktualny czas: 23.08.2025 - 23:24