Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

 
Reply to this topicStart new topic
> LEFT JOIN pobierający określone rekordy, "inteligentne" złączenie tabel, wiele do jednego
Pilsener
post 15.05.2009, 08:57:22
Post #1





Grupa: Zarejestrowani
Postów: 1 590
Pomógł: 185
Dołączył: 19.04.2006
Skąd: Gdańsk

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


Hej, mam np. tabelę klienci:

ID||Imię||Nazwisko

I tabelę akcje:
ID_klienta||unix_time||id_akcji

I chodzi mi o to, żeby wyświetlić listę klientów + akcje na zasadzie:
  1. SELECT * FROM klienci LEFT JOIN akcje ON akcje.id_klienta=klienci.id


Jednak jeden klient może mieć wiele akcji, a mi zależy na tym, aby wyświetlić tylko ostatnią akcję (czyli tą, gdzie time ma największą wartość)

Próbowałem coś w stylu:
  1. SELECT * FROM klienci LEFT JOIN(SELECT * FROM akcje ORDER BY time DESC LIMIT 1 ) akcje ON akcje.id_klienta=klienci.id
lecz nie chodzi i nie jestem pewny, czy właśnie tak to należy zrobić, czy może iść w inną stronę, stąd prośba do Was.
Go to the top of the page
+Quote Post
magnus
post 15.05.2009, 12:03:02
Post #2





Grupa: Zarejestrowani
Postów: 99
Pomógł: 15
Dołączył: 15.11.2007
Skąd: Nowogród Bobrz.

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


Może dodaj MAX() i GROUP BY:

Kod
SELECT k.*, MAX(a.unix_time) from klienci k LEFT JOIN akcje a ON a.id_klienta=k.ID GROUP BY k.ID


Ten post edytował magnus 15.05.2009, 12:03:42


--------------------
Efemental.pl - nasz punkt słyszenia :: recenzje :: tylko metal!
Opensource'owy klon Cantra: http://github.com/magnax/Simtr
Go to the top of the page
+Quote Post
Pilsener
post 15.05.2009, 12:29:40
Post #3





Grupa: Zarejestrowani
Postów: 1 590
Pomógł: 185
Dołączył: 19.04.2006
Skąd: Gdańsk

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


Nic mi to nie daje, wiem jak wyciągnąć max(), jednak są dołączane także inne informacje dlatego bardzo mi zależy na tym, aby join dołączał tylko te rekordy, gdzie czas = max (po prostu chcę ostatnio dodaną akcję dla każdego użytkownika, a nie pierwszą lepszą). Wiem nawet jak dodać podzapytanie do LEFT JOIN, jednak strasznie mi to zamula bazę, a left join musi być, bo nie każdy użytkownik ma jakąś akcję sadsmiley02.gif

Ten post edytował Pilsener 15.05.2009, 12:31:10
Go to the top of the page
+Quote Post
heaven
post 15.05.2009, 20:58:15
Post #4





Grupa: Nieautoryzowani
Postów: 92
Pomógł: 15
Dołączył: 21.10.2006

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


  1. SELECT * FROM klienci LEFT JOIN (SELECT tab .* FROM (SELECT * FROM akcje a ORDER BY a.time DESC) AS tab GROUP BY tab.id_klienta) AS tab1 ON tab1.id_klienta = k.id;


nie wiem tylko czy spełni to Twoje oczekiwania jesli chodzi o szybkość

Ten post edytował heaven 15.05.2009, 20:59:26
Go to the top of the page
+Quote Post
Pilsener
post 16.05.2009, 10:30:47
Post #5





Grupa: Zarejestrowani
Postów: 1 590
Pomógł: 185
Dołączył: 19.04.2006
Skąd: Gdańsk

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


No niestety muli, podobnie jak uproszczona wersja tego:
  1. SELECT * FROM klienci LEFT JOIN(SELECT * FROM akcje ORDER BY time DESC) akcje ON akcje.id_klienta=klienci.id


Wszystko zmierza do tego, że będę musiał podzielić to na dwie tabele:
- aktualna_akcja - i przy każdej akcji updatować
- spis_akcji - i tu wrzucać normalnie insertem każdą akcję, by mieć ich spis

Najchętniej bym wrzucił id_aktualnej_akcji do tabeli klienci, ale jest ona bardzo duża a te akcje dotyczą jakiś 2-3% wszystkich klientów, więc nie ma sensu - LEFT JOIN'em bardzo szybko i sprawnie się to dołącza.
Go to the top of the page
+Quote Post
24xls
post 23.05.2009, 09:59:52
Post #6





Grupa: Zarejestrowani
Postów: 5
Pomógł: 0
Dołączył: 12.02.2008

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


Sprawdzone, działa. Sorry, ale nie wiem jak wstawić znacznik SQL do tego posta ;>

select

klient.*,

aukcja.unix_time,

aukcja.id_aukcji

from

klient

join

(

select

a.*

from

aukcja a

join

(
select

id_klient,

max(unix_time)
as unix_time

from

aukcja

group
by id_klient

) ost_a

on

ost_a.unix_time = a.unix_time

and

ost_a.id_klient = a.id_klient

) aukcja

on

klient.id = aukcja.id_klient

Go to the top of the page
+Quote Post
Spawnm
post 23.05.2009, 10:27:23
Post #7





Grupa: Moderatorzy
Postów: 4 069
Pomógł: 497
Dołączył: 11.05.2007
Skąd: Warszawa




24xls -> zaznaczasz treść która ma być w bbcode sqla i klikasz button {sql}kliknij [cytuj] mój post i zobacz jak jest u mnie , i popraw . potem swój usunę .
  1. SELECT
  2.  
  3. klient.*,
  4.  
  5. aukcja.unix_time,
  6.  
  7. aukcja.id_aukcji
  8.  
  9. FROM klient JOIN ( SELECT a.*
  10.  
  11. FROM aukcja a
  12.  
  13. JOIN ( SELECT id_klient,
  14.  
  15. max(unix_time) AS unix_time
  16.  
  17. FROM aukcja GROUP BY id_klient
  18.  
  19. ) ost_a ON ost_a.unix_time = a.unix_time AND ost_a.id_klient = a.id_klient
  20.  
  21. ) aukcja ON klient.id = aukcja.id_klient


Ten post edytował Spawnm 23.05.2009, 10:32:23
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: 22.06.2025 - 12:19