![]() |
![]() ![]() |
![]() |
![]() ![]()
Post
#1
|
|
![]() Grupa: Zarejestrowani Postów: 164 Pomógł: 3 Dołączył: 13.12.2007 Ostrzeżenie: (0%) ![]() ![]() |
Witam
Pobieram z kilku tabel produkty, producentów i opisy produktów w 2 językach. Pobieram obie wersje językowe opisów bo póki co wersji obcojęzycznych jest znikoma ilość i to co się da tłumaczę przez php z automatu. Problem: Jak wykluczyć w zapytaniu polską wersję opisu produktu jeśli istnieje obcojęzyczna ? W tabeli 'produkty' każdy produkt ma unikalny ID. W tabeli 'opisy' każdy opis ma odpowiedni ID produktu i oprócz tego oznaczenie języka np. 'pl', 'en'. Czy rozwiązaniem byłoby podzapytanie w rodzaju [SQL] pobierz, plaintext
Musiałbym wtedy wywalić z tablicy (uzyskanej przez while($r = mysql_fetch_array($rekord)){}) te rekordy z opisem 'pl', które mają swój odpowiednik 'en'... Jak ? ? Proszę o pomoc, podpowiedzi. Ten post edytował kleszczoscisk 4.09.2009, 14:58:08 |
|
|
![]()
Post
#2
|
|
![]() Grupa: Moderatorzy Postów: 4 362 Pomógł: 714 Dołączył: 12.02.2009 Skąd: Jak się położę tak leżę :D ![]() |
Jeśli product_id jest niezależny od języka, a sądząc z opisu jaki podałeś jest to prawda, to zapytanie może tak wyglądać. Ale spojrzawszy szerzej na to co napisałeś to odnosi się wrażenie, że id jest kluczem głównym i samo w sobie jest już unikatowe, więc nie trzeba go jeszcze distinct traktować (mogę się jednak mylić bo nic nie pisałeś o kluczach), czyli można tę klauzulę wyrzucić i ograniczyć do SELECT product_id FROM products. Dodatkowo dziwne byłoby to zapytanie w WHERE.
By zrobić to o czym piszesz czyli mieć listę wszystkich produktów w bazie, ale tak, że bierzemy wszystkie produkty z obcojęzycznym opisem i dokładamy do niego te z opisem polskim by zrobić komplet, trzeba posłużyć się UNION ![]() Opiszę Ci jak to by wyglądało, ale algorytmem. Zapytanie będzie jako zadanie domowe ![]() 1. Weź z tablicy opisów id_produktów wszystkich rekordów gdzie są obcojęzyczne opisy. Możesz uściślić o jaki język Ci konkretnie chodzi. 2. Teraz rekordy o pobranych id _produktu połącz z tabelami opisów i innymi Cię interesującymi jak chcesz by otrzymać interesujące Cię dane. 3. Z tabel połączonych z polskimi opisami wybierz te, które nie posiadają takich id jak te wybrane wcześniej i połącz z tabelami innymi wedle uznania. 4. Połącz wyniki obu zapytań. Ten post edytował thek 4.09.2009, 15:08:07 -------------------- Najpierw był manual... Jeśli tam nie zawarto słów mądrości to zapytaj wszechwiedzącego Google zadając mu własciwe pytania. A jeśli i on milczy to Twój problem nie istnieje :D
|
|
|
![]()
Post
#3
|
|
![]() Grupa: Zarejestrowani Postów: 164 Pomógł: 3 Dołączył: 13.12.2007 Ostrzeżenie: (0%) ![]() ![]() |
Dzięki, zaraz będę to analizował. Wydaje mi się jednak (może źle), że chyba lepiej byłoby znaleźć jakiś sposób na odfiltrowanie z tablicy rekordów: jeśli jest rekord z językiem 'en' to wywal rekord o tym samym ID z językiem 'pl'
Powinienem chyba jeszcze dołączyć strukturę tabel: products: id*| id_kategorii | id_producenta | obrazek | ... products_translations: id* | product_id | lang | opis | ... Witam No niestety nie udało mi się nic z tym problemem zrobić. Próbuję z innej strony: filtrowanie tablicy jaką dostaję po wyciągnięciu z bazy. Wygląda ona mniej więcej tak: Kod Array ( [id] => 101 [id_opisu] => 1 [lang] => pl [opis] => to jest opis polski pierwszego produktu ) Array ( [id] => 101 [id_opisu] => 2 [lang] => en [opis] => first product - description in english ) Array ( [id] => 102 [id_opisu] => 3 [lang] => en [opis] => second product - description in english ) Array ( [id] => 103 [id_opisu] => 4 [lang] => pl [opis] => trzeci produkt, opis polski ) Gdzie
... i jak wywalić z tej tablicy rekord z opisem polskim jeśli istnieje jego odpowiednik o tym samym 'id' z 'opise'm w języku angielskim ? Czyli w tym przypadku pierwszy rekord ? Ten post edytował kleszczoscisk 4.09.2009, 15:18:28 |
|
|
![]()
Post
#4
|
|
![]() Grupa: Moderatorzy Postów: 4 362 Pomógł: 714 Dołączył: 12.02.2009 Skąd: Jak się położę tak leżę :D ![]() |
No to popatrz dokładnie na mój opis. Połącz tabele products i products translations tak jak zazwyczaj, ale wybierz z niej TYLKO te, które mają lang = en. To jest Twoja pierwsza część.
Teraz musisz z tabel połączonych jak poprzednio wybrać wszystkie z lang = pl, ale dodatkowo musisz zaznaczyć, że nie mogą to być rekordy, które mają id takie same jak te z pierwszej paczki.
Całość ładnie łączymy UNION. Tylko pamiętaj... Liczba i ilość kolumn muszą się zgadzać bo inaczej Ci wywali baza błąd. Powiedz więc... Czy właśnie podany przepis na zapytanie z wynikami nie jest aby tym co chcesz i co opisałem dokładnie w moim poście sprzed pół tygodnia? ![]() -------------------- Najpierw był manual... Jeśli tam nie zawarto słów mądrości to zapytaj wszechwiedzącego Google zadając mu własciwe pytania. A jeśli i on milczy to Twój problem nie istnieje :D
|
|
|
![]()
Post
#5
|
|
![]() Grupa: Zarejestrowani Postów: 164 Pomógł: 3 Dołączył: 13.12.2007 Ostrzeżenie: (0%) ![]() ![]() |
@thek dziękuję pięknie.
Podpowiedz mi jeszcze proszę: "Liczba i ilość kolumn muszą się zgadzać" - czyli muszę wybrać dokładnie te same kolumny w obu zapytaniach , po SELECT ? wybrane_kolumny ? Ten post edytował kleszczoscisk 8.09.2009, 21:47:23 |
|
|
![]()
Post
#6
|
|
![]() Grupa: Moderatorzy Postów: 4 362 Pomógł: 714 Dołączył: 12.02.2009 Skąd: Jak się położę tak leżę :D ![]() |
Tak tam gdzie wpisałem wybrane_kolumny muszą się one pojawić w takiej samej ilości i takiej samej kolejności. UNION jest specyficznym połączeniem, ponieważ zwyczajnie dodaje rekordy jednego zapytania do drugiego (ale olewa zdublowane!) i nie patrzy na nazwę kolumn tego co dołącza. Ważna jest dla niego tylko ilość kolumn. Jeśli przez przypadek podasz w pierwszym kolumny: Ala, ma, kota, a w drugim: Sierotka, ma, rysia, to tak dostaniesz, choć tylko ma oba te podzapytania mają wspólne. Nazwy kolumn przechodzą z tabeli pierwszej, więc odnosząc się do Ala rekordy z drugiego podzapytania będa miały zawartość tego co było w Sierotka, a tam na pewno nie są dane jakich byś się spodziewał.
-------------------- Najpierw był manual... Jeśli tam nie zawarto słów mądrości to zapytaj wszechwiedzącego Google zadając mu własciwe pytania. A jeśli i on milczy to Twój problem nie istnieje :D
|
|
|
![]()
Post
#7
|
|
![]() Grupa: Zarejestrowani Postów: 164 Pomógł: 3 Dołączył: 13.12.2007 Ostrzeżenie: (0%) ![]() ![]() |
Zapytanie wyszło kolosalne, a błąd wyskoczył taki:
Kod This version of MySQL doesn't yet support 'LIMIT & IN/ALL/ANY/SOME subquery' Kod $rekord = mysql_query("(SELECT prod_translations.pid , prod_translations.product_name , prod_translations.lang AS jezyk , prod_translations.description , prod_translations.active, prod_translations.isdefault , products.product_id, products.category_id, products.producer_id, products.in_stock, products.gfx, products.file, products.add_date, products.edit_date, products.price, products.promo, products.weight, products.views, products.category2, products.category3, products.sort, products.products_related, products.other_price, products.product_code, gfx.gfx_id , gfx.prod_id, gfx.name AS nazwapliku , gfx.main_gfx , gfx.unic_name , gfx.gfx_sort , manufacturers.producent_id , manufacturers.name AS autor , manufacturers.info , manufacturers.info_eng , manufacturers.web FROM `manufacturers` LEFT JOIN `products` ON manufacturers.producent_id = products.producer_id LEFT JOIN `prod_translations` ON products.product_id = prod_translations.pid LEFT JOIN `gfx` ON products.product_id = gfx.prod_id WHERE manufacturers.isdefault LIKE '%$art%' AND prod_translations.lang = 'en' AND gfx.main_gfx = 1 AND products.in_stock > 0 ORDER BY products.add_date DESC LIMIT ".($pagz*$ilez).", $ilez) UNION (SELECT prod_translations.pid , prod_translations.product_name , prod_translations.lang AS jezyk , prod_translations.description , prod_translations.active, prod_translations.isdefault , products.product_id, products.category_id, products.producer_id, products.in_stock, products.gfx, products.file, products.add_date, products.edit_date, products.price, products.promo, products.weight, products.views, products.category2, products.category3, products.sort, products.products_related, products.other_price, products.product_code, gfx.gfx_id , gfx.prod_id, gfx.name AS nazwapliku , gfx.main_gfx , gfx.unic_name , gfx.gfx_sort , manufacturers.producent_id , manufacturers.name AS autor , manufacturers.info , manufacturers.info_eng , manufacturers.web FROM `manufacturers` LEFT JOIN `products` ON manufacturers.producent_id = products.producer_id LEFT JOIN `prod_translations` ON products.product_id = prod_translations.pid LEFT JOIN `gfx` ON products.product_id = gfx.prod_id WHERE manufacturers.isdefault LIKE '%$art%' AND prod_translations.lang = 'pl' AND gfx.main_gfx = 1 AND products.in_stock > 0 AND products.product_id NOT IN (SELECT products.product_id FROM `manufacturers` LEFT JOIN `products` ON manufacturers.producent_id = products.producer_id LEFT JOIN `prod_translations` ON products.product_id = prod_translations.pid LEFT JOIN `gfx` ON products.product_id = gfx.prod_id WHERE manufacturers.isdefault LIKE '%$art%' AND prod_translations.lang = 'en' AND gfx.main_gfx = 1 AND products.in_stock > 0 ORDER BY products.add_date DESC LIMIT ".($pagz*$ilez).", $ilez) ORDER BY products.add_date DESC LIMIT ".($pagz*$ilez).", $ilez)") or die(mysql_error()); Tak myślę, że gdyby jednak zabrać się do tego przez przefiltrowanie wyników to może nadawać się będzie array_filter. Funkcja do której by się odwoływała musiałaby szukac w kluczu $w['id'] duplikatów i spośród nich usuwać elementy, które mają w kluczu $w['lang'] pl ... ? Help ![]() |
|
|
![]()
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 ![]() |
Jeśli tak to porządny serwer sobie załatw, bo takie errory to bodajże gdzieś w Mysql 3.X były, a 5.X już od jakiegoś czasu jest... Ostatni raz tego typu błąd widziałem chyba 2-3 lata temu. Dlatego myślę,że jakiś naprawdę stary serwer masz w użytku. Czyżby Krasnal?
![]() Patrząc na kod chyba wszystko wrzucasz jako kolumny. Jeśli tak jest to zastosuj składnię: nazwa_tablicy.* lub wręcz samo *. Ale wybieranie wszystkiego to bezsens. Bierz tylko potrzebne kolumny. Dzięki temu przyspieszasz zapytanie poprzez zmniejszenie ilości przesyłanych danych. I zapytanie zmniejszysz. Ten post edytował thek 11.09.2009, 19:40:56 -------------------- Najpierw był manual... Jeśli tam nie zawarto słów mądrości to zapytaj wszechwiedzącego Google zadając mu własciwe pytania. A jeśli i on milczy to Twój problem nie istnieje :D
|
|
|
![]()
Post
#9
|
|
![]() Grupa: Zarejestrowani Postów: 164 Pomógł: 3 Dołączył: 13.12.2007 Ostrzeżenie: (0%) ![]() ![]() |
To płatny współdzielony hosting w popularnej polskiej firmie... Wybieram tylko niezbędne pola, z których dane użyte będą później w pętli while. Bardzo doceniam Twoje podpowiedzi ale noie przestaje mnie nurtować, czy pobierając dane z bazy prostszym i mniej obciążającym zapytaniem i później filtrując tę tablicę jakoś ... nie wyjdzie na to samo ?
|
|
|
![]()
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 ![]() |
Wszystko zależy od potrzebnych nam danych i ich struktury. Czasem nie ma sensu robić kosmicznych zapytań, ale zazwyczaj silnik bazy jest szybszy niż interpreter kodu php. Operacje tablicowe więc trwają z reguły dłużej niż identyczne w wyniku zapytanie do bazy. Dlatego ludzie czasem bardziej wolą zrobić ciut bardziej skomplikowane zapytanie niż próbować je zaprogramować skryptem.
-------------------- Najpierw był manual... Jeśli tam nie zawarto słów mądrości to zapytaj wszechwiedzącego Google zadając mu własciwe pytania. A jeśli i on milczy to Twój problem nie istnieje :D
|
|
|
![]() ![]() |
![]() |
Wersja Lo-Fi | Aktualny czas: 10.07.2025 - 06:55 |