[MySQL] unikalne numery podwozia
Tomek - 17-05-2007 22:44
[MySQL] unikalne numery podwozia
Potrzebuję pobrać ilość oraz średnią cenę samochodów spełniających odpowiednie kryteria. Kryteria zapisane są w tabeli 'kryteria' (o polach: car_id, equipments_id, value), są to m.in. przebieg, typ silnika itd. Wyciągam tak: SELECT count(DISTINCT c.id) AS count, AVG(end_price) AS price FROM cars AS c LEFT JOIN kryteria AS ce ON ce.car_id = c.id WHERE c.brand_id = 22 AND ce.car_id in (select ce.car_id from kryteria ce where ce.equipment_id = 70 AND (ce.value > 0 AND ce.value <= 3)) AND ce.car_id in (select ce.car_id from kryteria ce where ce.equipment_id = 66 AND ce.value = 1
Mój problem polega na tym że jedno z kryterium (equipments_id = 18) to nr podwozia a w tabeli 'kryteria' zapisanych jest wiele wpisów w różnym 'car_id' ale jednakowym numerze silnika. *Pobrane samochody muszą mieć unikalne numery podwozia* , rekordów jest kilkadziesiąt tysięcy. Jak to zrobić ??? Kombinuje tak że dodaje do zapytania linię: AND ce.car_id in (select distinct value from kryteria where equipment_id = 18)
=?ISO-8859-2?Q?Pawe=B3_Matejski?= - 17-05-2007 22:44
Tomek wrote: > Potrzebuję pobrać ilość oraz średnią cenę samochodów spełniających odpowiednie kryteria. > Kryteria zapisane są w tabeli 'kryteria' (o polach: car_id, equipments_id, value), są to m.in. przebieg, typ silnika itd. Wyciągam tak: > SELECT count(DISTINCT c.id) AS count, > AVG(end_price) AS price > FROM cars AS c > LEFT JOIN kryteria AS ce ON ce.car_id = c.id > WHERE c.brand_id = 22 > AND ce.car_id in (select ce.car_id from kryteria ce where ce.equipment_id = 70 AND (ce.value > 0 AND ce.value <= 3)) > AND ce.car_id in (select ce.car_id from kryteria ce where ce.equipment_id = 66 AND ce.value = 1
Czemu w powyższych 2 warunkach używasz ca.car_id, a nie c.d? I wtedy join nie jest Ci potrzebny! A to on Ci komplikuje sprawę.
> Mój problem polega na tym że jedno z kryterium (equipments_id = 18) to nr podwozia > a w tabeli 'kryteria' zapisanych jest wiele wpisów w różnym 'car_id' ale jednakowym numerze silnika. > *Pobrane samochody muszą mieć unikalne numery podwozia* , rekordów jest kilkadziesiąt tysięcy. > Jak to zrobić ??? Kombinuje tak że dodaje do zapytania linię: > AND ce.car_id in (select distinct value from kryteria where > equipment_id = 18)
Dublujesz informacje? Trzymasz to samo w car_id i value? Czy lubisz pzyrównywać wagę z kolorem oczu? A abstrahując od znaczenia kolumn, distinct w tym miejscu nic nie zmienia.
-- P.M.
Tomek - 17-05-2007 22:44
> Czemu w powyższych 2 warunkach używasz ca.car_id, a nie c.d? I wtedy join nie > jest Ci potrzebny! A to on Ci komplikuje sprawę. > Zmieniłem zapytanie na: SELECT count(DISTINCT c.id) AS count, AVG(end_price) AS price FROM cars AS c WHERE c.brand_id = 22 AND c.id in (select ce.car_id from kryteria ce where ce.equipment_id = 70 AND (ce.value > 0 AND ce.value <= 3)) AND c.id in (select ce.car_id from kryteria ce where ce.equipment_id = 66 AND ce.value = 1)
Zwraca ten sam wynik co poprzednie.
> Dublujesz informacje? Trzymasz to samo w car_id i value? Czy lubisz > pzyrównywać wagę z kolorem oczu? > A abstrahując od znaczenia kolumn, distinct w tym miejscu nic nie > zmienia.
AND c.id in (select ce.car_id value from kryteria ce where equipment_id = 18 group by value) Czy to ma sens ? Nie jestem w stanie sprawdzić czy zapytanie zwraca prawidłowe wyniki bo mam aktualnie dostęp tylko do bazy testowej...
=?ISO-8859-2?Q?Pawe=B3_Matejski?= - 17-05-2007 22:44
Tomek wrote: >> Czemu w powyższych 2 warunkach używasz ca.car_id, a nie c.d? I wtedy join nie >> jest Ci potrzebny! A to on Ci komplikuje sprawę. >> > Zmieniłem zapytanie na: > SELECT count(DISTINCT c.id) AS count, > AVG(end_price) AS price > FROM cars AS c > WHERE c.brand_id = 22 > AND c.id in (select ce.car_id from kryteria ce where ce.equipment_id = 70 AND (ce.value > 0 AND ce.value <= 3)) > AND c.id in (select ce.car_id from kryteria ce where ce.equipment_id = 66 AND ce.value = 1) > > Zwraca ten sam wynik co poprzednie.
A poprzedni był błędny? :) Wynik dla średniej będzie różny, tylko wtedy, kiedy do różnych samochodów miałeś różną ilość kryteriów - a to i tak może być zamaskowane przez rozkład cen. Usuń z count distinct (bo dla poprawnej wersji jest on niepotrzebny) i po nim orientuj się czy zwracana jest poprawna ilość samochodów. Zresztą w ogóle zapytania najlepiej debugować po wyrzuceniu funkcji agregujących.
>> Dublujesz informacje? Trzymasz to samo w car_id i value? Czy lubisz >> pzyrównywać wagę z kolorem oczu? >> A abstrahując od znaczenia kolumn, distinct w tym miejscu nic nie >> zmienia. > > AND c.id in (select ce.car_id value from kryteria ce where equipment_id = 18 group by value) > Czy to ma sens ?
Zakładając, że ten pierwszy value to przez przypadek ci się zaplątał, to wyeliminowałeś tylko pierwszą bezsensowność. Ale drugą już nie. Tzn. że operatorem IN nie spowodujesz unikalności danych przez nawet najbardziej skomplikowane podzapytanie.
> Nie jestem w stanie sprawdzić czy zapytanie zwraca prawidłowe wyniki bo mam aktualnie dostęp tylko do bazy testowej...
Ciekawe uzasadnienie... ja, jeśli mam tego rodzaju problem, to w dokładnie odwrotnym przypadku, bo do bazy testowej mogę wprowadzać dowolne dane, a do bazy produkcyjnej już nie. ;)
-- P.M.
Tomek - 17-05-2007 22:44
> A poprzedni był błędny? :) Wynik dla średniej będzie różny, tylko > wtedy, kiedy do różnych samochodów miałeś różną ilość > kryteriów - a to i tak może być zamaskowane przez rozkład cen. Usuń > z count distinct (bo dla poprawnej wersji jest on niepotrzebny) i po nim > orientuj się czy zwracana jest poprawna ilość samochodów. > Zresztą w ogóle zapytania najlepiej debugować po wyrzuceniu funkcji > agregujących. >
Gdy usunę distinct (i warunek o nr. podwozia) rekordy (id) powtarzają się ale tym się na razie nie przejmuję.
>> AND c.id in (select ce.car_id value from kryteria ce where >> equipment_id = 18 group by value) Czy to ma sens ? > > Zakładając, że ten pierwszy value to przez przypadek ci się > zaplątał, to wyeliminowałeś tylko pierwszą bezsensowność. Ale > drugą już nie. Tzn. że operatorem IN nie spowodujesz unikalności > danych przez nawet najbardziej skomplikowane podzapytanie.
Nie rozumiem, moimi zdaniem tylko IN ma tu rację bytu a podzapytanie zwraca wszystkie idiki o uikalnych nr. podwozia. Chodź słyszałem że z IN może to bardzo wolno działać.
=?ISO-8859-2?Q?Pawe=B3_Matejski?= - 17-05-2007 22:44
Tomek wrote: >>> AND c.id in (select ce.car_id value from kryteria ce where >>> equipment_id = 18 group by value) Czy to ma sens ? >> Zakładając, że ten pierwszy value to przez przypadek ci się >> zaplątał, to wyeliminowałeś tylko pierwszą bezsensowność. Ale >> drugą już nie. Tzn. że operatorem IN nie spowodujesz unikalności >> danych przez nawet najbardziej skomplikowane podzapytanie. > > Nie rozumiem, moimi zdaniem tylko IN ma tu rację bytu a podzapytanie > zwraca wszystkie idiki o uikalnych nr. podwozia. > Chodź słyszałem że z IN może to bardzo wolno działać.
IN stosuje się w where. W where warunki odnoszą się do jednego rekordu i nie mają "pojęcia" o innych. Inaczej mówiąc niezależnie czy po prawej stronie IN będzie (1,2) czy (1,1,2,2) to rekord warunek spełni, niezależnie czy jest pierwszym, czy n-tym, dla którefo pole car_id ma wartość 1 lub 2.
-- P.M.
Tomek - 19-05-2007 00:01
Częściowo rozwiązałem to tak, że filtruję w PHP powtarzające się rekordy funkcją http://pl.php.net/manual/pl/function...ique.php#68339
Niestety to nie koniec, muszę policzyć wszystkie samochody w bazie o niepowtarzającym się numerze silnika.
SELECT count(c.id) FROM cars AS c LEFT JOIN kryteria AS ce ON ce.car_id = c.id WHERE ce.equipment_id = 18
Jak to zrobić ?
=?ISO-8859-2?Q?Pawe=B3_Matejski?= - 19-05-2007 00:01
Tomek wrote: > Częściowo rozwiązałem to tak, że filtruję w PHP powtarzające się > rekordy funkcją > http://pl.php.net/manual/pl/function...ique.php#68339
To to chyba ta brzytwa, której chwyta sie tonący.
> Niestety to nie koniec, muszę policzyć wszystkie samochody w bazie o > niepowtarzającym się numerze silnika. > > SELECT count(c.id) FROM cars AS c > LEFT JOIN kryteria AS ce ON ce.car_id = c.id WHERE ce.equipment_id = 18 > > Jak to zrobić ?
Po co Ci LEFT JOIN ? I po co Ci tu tablica cars?
SELECT count(distinct value) FROM kryteria WHERE equipment_id = 18
P.S. Ty podaj jakieś przykładowe wartości z tych Twoich tabel, bo coś masz dziwnie problemy, przy teoretycznie dobrze zaprojektowanej bazie?
-- P.M.
zanotowane.pldoc.pisz.plpdf.pisz.pleffulla.pev.pl
|
[mysql] =?ISO-8859-2?Q?Za=E6mienie=2E=2E=2E_jak_wy=B6wietli=E6?==?ISO-8859-2?Q?=2E=2E=2E?=
[mysql] =?ISO-8859-2?Q?wielko=B6=E6_bazy_a_stabilno=B6=E6=2C?==?ISO-8859-2?Q?_podzia=B3_du=BFej_bazy_a_powi=B1zania_tabel?=
[MySQL] =?ISO-8859-2?Q?Wy=B6wietlenie_kolejnej_pozycji=2C_?==?ISO-8859-2?Q?jak=B1_mia=B3by_dany_rekord=2C_gdybym_czyta=B3 _?==?ISO-8859-2?Q?wg_konkretnych_kryteri=F3w=2E_Da_si=EA_=3F?=
[mysql 4.0.x] przenoszenie kolum =?ISO-8859-2?Q?mi=EAdzy_bazam?==?ISO-8859-2?Q?i_cd_=2E=2E=2E_?=
[MySQL] =?ISO-8859-2?Q?z=B3=B1czenie_tabeli_u=BFytkownik_i?==?ISO-8859-2?Q?_zdj=EAcia_z_wyborem_zdj=EAcia_domy=B6lnego?=
[MySQL] Jak =?ISO-8859-2?Q?wpisa=E6_do_tabeli_pozycje_dl?==?ISO-8859-2?Q?a_wierszy_gdybym_te_wiersze_wybiera=B3_w_ok?== ?ISO-8859-2?Q?re=B6lonej_kolejno=B6ci_=3F?=
Gdzie MySQL 4.1, a gdzie 5.0?
[MySQL 4.0...4.1] zabezpieczenie przed =?ISO-8859-2?Q?jednoczesn?==?ISO-8859-2?Q?=B1_edycj=B1?=
[MS SQL] "set names" (mySQL) w MS SQL
[mysql 5.x] jak =?ISO-8859-2?Q?zrealizowa=E6_zapytanie=3F_cz?==?ISO-8859-2?Q?yli_podzapytanie_i_wi=EAcej_ni=BF_jeden_rz=B1? ==?ISO-8859-2?Q?d_wynik=F3w?=
zanotowane.pldoc.pisz.plpdf.pisz.ploefg.opx.pl
Cytat
Decede mihi sole - nie zasłaniaj mi słonca. Gdy kogoś kochasz, jesteś jak stworzyciel świata - na cokolwiek spojrzysz, nabiera to kształtu, wypełnia się barwą, światłem. Powietrze przytula się do ciebie, choćby był mróz, a ty masz w sobie tyle radości, że musisz ją rozdawać wokoło, bo się w tobie nie mieści Hoc fac - tak czyń. A tergo - od tyłu; z tyłu. I czarne włosy posiwieją. Safona |
|