Skocz do zawartości
Zaloguj się, aby obserwować  
psw779

[mysql] zapytanie - łączenie dwóch tabel - pilny problem

Polecane posty

Mam taką strukturę w bazie:

 

Tabela galleries

id [int (11)]

date [date]

time [time]

name [varchar (150)]

 

Tabela pictures

id [int (11)]

idg [int (11)]

date [date]

time [time]

title [varchar (150)]

 

Chciałbym jednym zapytanie wyciągnąć 10 galerii do których ostatnio zostały dodane zdjęcia. Dodam jeszcze, że oprócz ID potrzebuje wyciągnąć jeszcze tytuł ostatnio dodanej fotki więc samo MAX(id) z tabeli pictures nie wystarczy.

 

Męczę się już z tym sporo i zatrzymałem się mniej więcej na tym że najpierw działa klauzula GROUP BY a potem ORDER BY co uniemożliwia mi posortowanie tego tak jak bym chciał.

Udostępnij ten post


Link to postu
Udostępnij na innych stronach
Męczę się już z tym sporo i zatrzymałem się mniej więcej na tym że najpierw działa klauzula GROUP BY a potem ORDER BY co uniemożliwia mi posortowanie tego tak jak bym chciał.

Przy grupowaniu do sortowania wyników służy klauzula HAVING

Udostępnij ten post


Link to postu
Udostępnij na innych stronach

@regdos - oświecisz mnie, w jaki sposób przy pomocy HAVING _posortujesz_ wyniki np. malejąco po kluczu?

Mi zawsze się wydawało, że having to upraszczając takie where ale w odniesieniu do całych grup :)

 

Jedyne, co (w przypadku MySQL) mi przychodzi obecnie do głowy, to

SELECT DISTINCT idg FROM `pictures` ORDER BY id desc LIMIT 5

Dostaniesz wtedy pięć galerii, w których zostały dodane nowe fotki.

Znalezienie tej konkretnej, której to dotyczy, będzie dosyć skomplikowane (jeśli jest to ogólnie możliwe), a jak nawet uda się coś skonstruować, to potworka zajeżdżającego całą bazę.

Może warto by stworzyć dodatkową kolumnę w liście galerii i tam wysyłać ID ostatniej fotki + timestamp przy jej dodawaniu?

Wtedy wyszukanie czegoś takiego, to bułka z masłem :D

Udostępnij ten post


Link to postu
Udostępnij na innych stronach
@regdos - oświecisz mnie, w jaki sposób przy pomocy HAVING _posortujesz_ wyniki np. malejąco po kluczu?

Mi zawsze się wydawało, że having to upraszczając takie where ale w odniesieniu do całych grup :)

Oczywiście masz racje coś mi się pomieszało :D

Udostępnij ten post


Link to postu
Udostępnij na innych stronach
Mam taką strukturę w bazie:

 

Tabela galleries

id [int (11)]

date [date]

time [time]

name [varchar (150)]

 

Tabela pictures

id [int (11)]

idg [int (11)]

date [date]

time [time]

title [varchar (150)]

 

Chciałbym jednym zapytanie wyciągnąć 10 galerii do których ostatnio zostały dodane zdjęcia. Dodam jeszcze, że oprócz ID potrzebuje wyciągnąć jeszcze tytuł ostatnio dodanej fotki więc samo MAX(id) z tabeli pictures nie wystarczy.

 

Męczę się już z tym sporo i zatrzymałem się mniej więcej na tym że najpierw działa klauzula GROUP BY a potem ORDER BY co uniemożliwia mi posortowanie tego tak jak bym chciał.

A to że musi być jednym zapytaniem to tak ambicjonalnie sobie zadanie postawiłeś? Stwórz tabelę tymczasową z ostatnimi 10 galeriami w których dodano zdjęcia, a potem drugim zapytaniem zrób joina z pictures.

Udostępnij ten post


Link to postu
Udostępnij na innych stronach
A to że musi być jednym zapytaniem to tak ambicjonalnie sobie zadanie postawiłeś? Stwórz tabelę tymczasową z ostatnimi 10 galeriami w których dodano zdjęcia, a potem drugim zapytaniem zrób joina z pictures.

Ale co ci to da?

Zapytanie generujące N ostatnich galerii, w których dodano zdjęcia wcześniej napisałem.

Tylko, że nie dowiążesz w żaden prosty sposób do nich ostatniego z rekordów im odpowiadającego.

Co najwyżej w jakiejś pętli for cyklicznie wykonywać

SELECT MAX(id) FROM ... WHERE galeria = [:id:]

gdzie :id: to każdy z elementów zwróconych przez poprzednie zapytanie.

 

IMO łatwiej jednak będzie dodać przy dodawaniu nowych zdjęć aktualizację, że ostatnim zdjęciem w galerii jest zdjęcie o ID=$x i jest dodane o czasie $timestamp.

Wówczas wyciągnięcie danych o ostatnich zdjęciach to jeden prosty select.

Udostępnij ten post


Link to postu
Udostępnij na innych stronach

SELECT galleries.name, pictures.title, pictures.time FROM galleries, pictures WHERE galleries.id = pictures.idg AND pictures.id = (SELECT id FROM pictures WHERE idg = galleries.id ORDER BY time DESC LIMIT 1) GROUP BY galleries.id ORDER BY pictures.time DESC LIMIT 10

 

zamiast 2 kolumn date i time, mozesz zrobic jedna o typie datetime, w powyzszym przykladzie kolumna 'time'

powinno dzialac, tyle ze jak widac, dla Ciebie i php to bedzie jedno zapytanie, dla mysql juz nie :)

ale jak juz bedziesz mial te miliony odwiedzin, to mozesz cachowac

 

 

@regdos - oświecisz mnie, w jaki sposób przy pomocy HAVING _posortujesz_ wyniki np. malejąco po kluczu?
A przeczytałeś chociaż, co napisałem za komentarz pod tym zapytaniem?
Ale co ci to da?

czy Ty masz jakies problemy emocjonalne ? 3 wypowiedzi w temacie i w każdej atak słowny

wystarczy powiedzieć co jest źle, poprzez argumentem i tyle; potem tylko czekac na ładne dziekuje;

 

 

edit:

SELECT galleries.name, pictures.title, pictures.time FROM galleries, pictures WHERE pictures.id = (SELECT id FROM pictures WHERE idg = galleries.id ORDER BY time DESC LIMIT 1) GROUP BY galleries.id ORDER BY pictures.time DESC LIMIT 10

 

niepotrzebne sprawdzanie galleries.id = pictures.idg w pierwszym zapytaniu

Udostępnij ten post


Link to postu
Udostępnij na innych stronach
Ale co ci to da?

Zapytanie generujące N ostatnich galerii, w których dodano zdjęcia wcześniej napisałem.

 

Błędnie, bo nie zadziała. A konkretnie to nie ma tam żadnego powiązania ostatnich id zdjęć z galeriami do których zostały dodane.

 

Tylko, że nie dowiążesz w żaden prosty sposób do nich ostatniego z rekordów im odpowiadającego.

Co najwyżej w jakiejś pętli for cyklicznie wykonywać

SELECT MAX(id) FROM ... WHERE galeria = [:id:]

gdzie :id: to każdy z elementów zwróconych przez poprzednie zapytanie.

 

IMO łatwiej jednak będzie dodać przy dodawaniu nowych zdjęć aktualizację, że ostatnim zdjęciem w galerii jest zdjęcie o ID=$x i jest dodane o czasie $timestamp.

Wówczas wyciągnięcie danych o ostatnich zdjęciach to jeden prosty select.

 

Eeee.... przekombinowane - nie mnóż bytów ponad konieczność.

 

Robisz tymczasową tabelę:

create temporary table maxidingal select max(id) as maxid, idg from pictures group by idg order by maxid desc limit 10;

 

A potem wyciągasz zdjęcia:

select pictures.* From pictures, maxidingal where maxid=id order by id desc;

 

I nawet joina nie trzeba.

Udostępnij ten post


Link to postu
Udostępnij na innych stronach

Bądź aktywny! Zaloguj się lub utwórz konto

Tylko zarejestrowani użytkownicy mogą komentować zawartość tej strony

Utwórz konto

Zarejestruj nowe konto, to proste!

Zarejestruj nowe konto

Zaloguj się

Posiadasz własne konto? Użyj go!

Zaloguj się

Zaloguj się, aby obserwować  

×