MySQL czy wystarczy jedno zapytanie?

0

Witam!

Plus minus mam taką strukturę bazy

produkty
prod_id
prod_opis

wersje
wers_id
wers_opis

kolory
kolor_id
kolor_opis

kombinacje
komb_id
prod_id
wers_id
kolor_id

ceny
cena_id
komb_id
cena

Innymi słowy mówiac każdy produkt może wystąpić w każdej wersji i w kazdym kolorze. Do kombinacji produkt, wersja, kolor jest przypisana indywidualna cena. W tabeli ceny będą zapisywane ceny łaczenie z historią. Np dla prod_id=5

kombinacje
komb_id prod_id wers_id kolo_id
7 5 1 1

ceny
cena_id komb_id cena
4 7 10,27
23 7 11,79
79 7 13,91

Mój problem polega na tym, jak pobrać listę wszystkich produktów we wszystkich wersjach i kolorach ale z ceną o najwyższym id_ceny (żeby nie brał pod uwagę historii). Chciałbym zrobić to bez uzywania podzapytań, gdyż produktów będzie ok 1500, każdy może wystąpić w ok 4 wersjach i w 7 kolorach co nam daje w sumie 42000 rekordów.

Jak na razie mam takie cos:

SELECT prod_opis, wers_opis, kolor_opis, cena 
FROM ceny, kombinacje, produkty, wersje, kolory where
produkty.prod_id=kombinacje.prod_id AND 
kombinacje.wers_id=wersje.wers_id AND 
kombinacje.kolor_id=kolory.kolor_id AND 
kombinacje.komb_id=ceny.komb_id 
group by(kombinacje.komb_id)

tyle ze to zwraca mi cenę z najniższą price_id dla danego komb_id.

0
 
SELECT prod_opis, wers_opis, kolor_opis, cena 
FROM ceny, kombinacje, produkty, wersje, kolory WHERE
produkty.prod_id=kombinacje.prod_id AND 
kombinacje.wers_id=wersje.wers_id AND 
kombinacje.kolor_id=kolory.kolor_id AND 
kombinacje.komb_id=ceny.komb_id AND
cena_id=(SELECT max(cena_id) from ceny where ceny.komb_id=kombinacje.komb_id)
GROUP BY(kombinacje.komb_id)

coś takiego działa, no ale jest podzapytanie, a jak będę pobierał kilkanaście/dziesiąt tyś rekordów to mi to raczej zmuli bazę...

1

Nie da się wykonać tego co chcesz jednym zapytaniem, bez użycia podazpytań. Kilkadziesiąt tysięcy rekordów to żaden problem. Jeśli jednak się tego obawiasz to lepiej pomyśleć nad inną budową bazy, np. aby historię cen trzymać w osobnej tabeli, bo do historii cen pewnie będziesz rzadko sięgał, a w tabeli ceny mieć aktualnie obowiązującą cenę. W takim scenariuszu w ogóle proponuję zrezygnować z tabeli kombinacie i ceny i złączyć je w jedno.

Poza tym twoja realizacja zapytania jest niezalecana. Lepiej użyć złączeń za pomocą join

select P.prod_opis, W.wers_opis, K.kolor_opis, C.cena
from kombinacje Kom
inner join produkty P on Kom.prod_id = P.prod_id
inner join wersje W on Kom.wers_id = W.wers_id
inner join kolory K on Kom.kolor_id = K.kolor_id
inner join ceny C on Kom.komb_id = C.komb_id
inner join (select komb_id, max(cena_id) maxCenaId from ceny group by komb_id) as maxC on C.komb_id = maxC.komb_id and C.cena_id = maxC.maxCenaId
0

też myślałem o wyrzuceniu historii cen do innej tabeli, ale bedzie jeszcze tabela zamówienia, która będzie się odwoływała do cen i nie wiadomo gdzie ta cena miała by być. Dzięki za pomoc. Skoro mówisz, że kiladziesiąt tysiecy rekordów potraktowanych podzapytaniem jest ok, to super:)

0

Tylko do łączenia tabel używaj join i będzie dobrze :)

1 użytkowników online, w tym zalogowanych: 0, gości: 1