![]() |
![]() |
![]()
Post
#1
|
|
Grupa: Zarejestrowani Postów: 56 Pomógł: 0 Dołączył: 15.02.2009 Ostrzeżenie: (0%) ![]() ![]() |
Mam tabelę z polami "tag" oraz "produkt". Może się zdarzyć że produkty maja takie same tagi, a więc zawartość pola tag często sie powtarza.
Chciałbym pobrać 5 najpopularniejszych tagów, ale nie chcę pisać 5 osobnych zapytan tylko optymalnie zmiescic sie w jednym. Na razie mam coś takiego:
Jak najlepiej dodać do tego pobieranie ilości wystąpień tagu? No i oczywiście jak ułożyć WHERE żeby pobrało 5 najpopularniejszych? Ten post edytował Haczyk67 5.12.2009, 15:55:35 |
|
|
![]() |
![]()
Post
#2
|
|
![]() Grupa: Zarejestrowani Postów: 6 476 Pomógł: 1306 Dołączył: 6.08.2006 Skąd: Kraków Ostrzeżenie: (0%) ![]() ![]() |
IMO masz zły projekt bazy danych. Produkty oraz Tagi to raczej relacja n-n, więc powinieneś mieć trzy tabele:
Produkt (id, nazwa) Tag (id, nazwa) ProduktTag (id_produkt, id_tag) A wybranie najpopularniejszych tagów to: COUNT() + GROUP BY + ORDER BY + LIMIT |
|
|
![]()
Post
#3
|
|
Grupa: Zarejestrowani Postów: 56 Pomógł: 0 Dołączył: 15.02.2009 Ostrzeżenie: (0%) ![]() ![]() |
Bazy już niestety zmienić nie moge.
Nie wiem czy dobrze Cię zrozumiełem. Sugerujesz że mam: 1) wysłać select COUNT(tag) from (...) 2)w php znaleść najpop. rekordy 3) wysłać zapytanie po 5 top rekordów używając group by ? |
|
|
![]()
Post
#4
|
|
![]() Grupa: Zarejestrowani Postów: 6 476 Pomógł: 1306 Dołączył: 6.08.2006 Skąd: Kraków Ostrzeżenie: (0%) ![]() ![]() |
Nie, powinieneś to zrobić bezproblemowo jednym zapytaniem:
1) Wybierasz: tag, COUNT(tag) - ewentualnie inne kolumny. Pamiętaj by dla COUNTa dodać sobie jakiś alias typu: cnt 2) Grupujesz wyniki wg kolumny tag 3) Sortujesz po wyniku COUNTa - czyli po wspomnianym aliasie cnt 4) Ograniczasz wyniki do 5-ciu |
|
|
![]()
Post
#5
|
|
Grupa: Zarejestrowani Postów: 56 Pomógł: 0 Dołączył: 15.02.2009 Ostrzeżenie: (0%) ![]() ![]() |
Chyba jednak przebuduje baze.
Ale to co podałeś id_produkt, id_tag <----- aktualnie mam coś takiego tylko zamiast id tagu mam nazwę tagu Czyli to samo co napisałem na początku. |
|
|
![]()
Post
#6
|
|
![]() Grupa: Zarejestrowani Postów: 6 476 Pomógł: 1306 Dołączył: 6.08.2006 Skąd: Kraków Ostrzeżenie: (0%) ![]() ![]() |
|
|
|
![]()
Post
#7
|
|
Grupa: Zarejestrowani Postów: 56 Pomógł: 0 Dołączył: 15.02.2009 Ostrzeżenie: (0%) ![]() ![]() |
Ale jeden tag może pasować do wielu różnych produktów a więc jeśli dam ID nic to niezmieni, dalej będę miał masę powtórzeń.
|
|
|
![]()
Post
#8
|
|
![]() Grupa: Zarejestrowani Postów: 6 476 Pomógł: 1306 Dołączył: 6.08.2006 Skąd: Kraków Ostrzeżenie: (0%) ![]() ![]() |
Tak, ale operowanie na liczbach jest nieporównywalnie lżejsze od męczenia się ze stringami.
|
|
|
![]()
Post
#9
|
|
Grupa: Zarejestrowani Postów: 56 Pomógł: 0 Dołączył: 15.02.2009 Ostrzeżenie: (0%) ![]() ![]() |
OK, w takim razie powiedz mi ktore rozwiazanie jest lepsze:
1) Produkt (id, nazwa) Tag (id, nazwa) ProduktTag (id_produkt, id_tag) <-- i tu masa duplikatów czy może 2) Produkt (id, nazwa, tagi(czyli np. "tag1, tag2")) Tag (id, nazwa, produkty(czyli np. "produkt1, produkt2") Aha i mówisz że liczby są lepsze, a więc tag1, tag2 i produkt1, produkt2 to ID |
|
|
![]()
Post
#10
|
|
![]() Grupa: Zarejestrowani Postów: 6 476 Pomógł: 1306 Dołączył: 6.08.2006 Skąd: Kraków Ostrzeżenie: (0%) ![]() ![]() |
Jakiekolwiek wyszukiwanie, porównywanie czy łączenie w drugim przypadku będzie katorgą. Poza tym nie chodzi o powtarzanie się jakichkolwiek danych, a o rzeczy typu: nazwa tagu, nazwa produktu itp., ID to co innego.
|
|
|
![]()
Post
#11
|
|
![]() Grupa: Moderatorzy Postów: 4 362 Pomógł: 714 Dołączył: 12.02.2009 Skąd: Jak się położę tak leżę :D ![]() |
Przy podziale:
Produkt (id, nazwa) Tag (id, nazwa) ProduktTag (id_produkt, id_tag) Nie ma żadnych duplikatów. Dlaczego? Wyjaśnię bo sam tego używam ( w nieco innej wersji ) i napisze JAK używam. Jeśli to UPDATE to wpierw usuwasz wszystkie wpisy w ProduktTag z danym id produktu. Potem robisz z tagów tablice (explode gdzie przecinek to delimiter), trimujesz elementy i robisz array_unique ![]() -------------------- 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
#12
|
|
Grupa: Zarejestrowani Postów: 56 Pomógł: 0 Dołączył: 15.02.2009 Ostrzeżenie: (0%) ![]() ![]() |
Ok w takim razie robię pierwszy projekt.
@thek pewnie dobrze mówisz ale niestety nie rozumiem z tego nic ;-) Aha i jeszcze co do tego zapytania to w pierwqszym projektcie bedzie działać to co podałeś? Cytat SELECT tag, COUNT(tag) AS tag_count FROM tbl_name GROUP BY tag ORDER BY tag_count DESC LIMIT 5;
Ten post edytował Haczyk67 9.12.2009, 18:18:53 |
|
|
![]()
Post
#13
|
|
![]() Grupa: Moderatorzy Postów: 4 362 Pomógł: 714 Dołączył: 12.02.2009 Skąd: Jak się położę tak leżę :D ![]() |
To może wytłumaczę Ci algorytm i na jego podstawie wyłapiesz co jest grane...
1. Pobierz pole z tagami. 2. Zrób z nich tablicę tagów. (explode) 3. Usuń z tablicy duble. (array_unique) 4. Utwórz zapytanie sprawdzające czy dane tagi są w bazie i zwracające. (zapytanie do tabeli TAG oparte o kilka LIKE 'tag') 5. Zrób z wyników zapytania tablicę. (choćby w pętli) 6. Wykryj różnicę pomiędzy Twoimi tagami a zwróconymi przez bazę. (array_diff) 7. Jeśli są jakieś, to owe "dodatkowe" dodaj do bazy i poznaj ich id_tag. (tu można na kilka sposobów) 8. Jeśli to UPDATE to usuń z ProduktTag wszystkie rekordy tyczące produktu o danym id_produkt. (tu nawet nie ma co się rozpisywać - delete ![]() 9. Dodaj do bazy ProduktTag rekordy z danym id_produkt i uzyskanymi id_tagów. (tu zwykły insert) To cały algorytm. Chyba już prościej się nie da. Następny krok to byłby gotowiec ![]() -------------------- 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
#14
|
|
Grupa: Zarejestrowani Postów: 56 Pomógł: 0 Dołączył: 15.02.2009 Ostrzeżenie: (0%) ![]() ![]() |
Użycie
Produkt (id, nazwa) Tag (id, nazwa) ProduktTag (id_produkt, id_tag) <--- tu znajduje sie troche duplikatów strasznie wsyzstko komplikuje i powoduje że będę musiał 1) pobrać wszystkie tagi (+distinct) 2) pętlą wykonać x zapytan (count(tag)) 3) porownac wszystkie tagi 4) pobrac 5 najpoularniejszych Nie mogę użyć tego co podałeś SELECT tag, COUNT(tag) AS tag_count FROM tbl_name GROUP BY tag ORDER BY tag_count DESC LIMIT 5; Prosze o rozwiązanie jak pobrać 5 tagów bo już przebudowałem bazę tak jak radziłeś i nie wiem jak to rozwikłać mimo paru dni staran. |
|
|
![]()
Post
#15
|
|
![]() Grupa: Zarejestrowani Postów: 6 476 Pomógł: 1306 Dołączył: 6.08.2006 Skąd: Kraków Ostrzeżenie: (0%) ![]() ![]() |
Cytat tu znajduje sie troche duplikatów Tam nie ma prawa być żadnego duplikatu - powinno Ci wywalić wtedy błąd, bo powinieneś mieć PRIMARYKEY(id_produkt, id_tag).Dlaczego nie możesz użyć tamtego zapytania? Jaki błąd wywala i jaka jest dokładna treść zapytania? |
|
|
![]()
Post
#16
|
|
![]() Grupa: Moderatorzy Postów: 4 362 Pomógł: 714 Dołączył: 12.02.2009 Skąd: Jak się położę tak leżę :D ![]() |
tu znajduje sie troche duplikatów Tu nie może być żadnego duplikatu. Każda para jest unikalna. Widocznie starych par nie usuwałeś. Patrz na PUNKT 8 z mojego ostatniego posta.Nie mogę użyć tego co podałeś Więc włącz myślenie. Skoro masz nazwy tabel Produkt, Tag, ProduktTag o podanej strukturze, to zapytanie musisz do tego DOPASOWAĆSELECT tag, COUNT(tag) AS tag_count FROM tbl_name GROUP BY tag ORDER BY tag_count DESC LIMIT 5; 1. Pogrupuj tagi z tabeli złączeniowej ProduktTag po id_tag i zrób count na tym polu. 2. By dodatkowo uzyskać nazwę-słowo. Połącz z tabelą Tag po jego id 3. Pole z nazwą (i ewentualnie id) tagu oraz ich ilość wrzuć do wyświetlanych kolumn. Jaki efekt?
Ten post edytował thek 15.12.2009, 10:23:52 -------------------- 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
#17
|
|
Grupa: Zarejestrowani Postów: 56 Pomógł: 0 Dołączył: 15.02.2009 Ostrzeżenie: (0%) ![]() ![]() |
Dzięks, już śmiga
Niestety pojawił się kolejny problem. Musze miec ilosć wystapien danego tagu. Jedyne co mi przychodzi do glowy to zapisać wyniki podanego przez was zapytania w tablicy $abcdef[x]['tag_ID']['tag_count'], potem pętlą pobranie nazw tagów o tym ID i dalej niestety nie mam pomysłu jak połączyć te dane. |
|
|
![]()
Post
#18
|
|
![]() Grupa: Moderatorzy Postów: 4 362 Pomógł: 714 Dołączył: 12.02.2009 Skąd: Jak się położę tak leżę :D ![]() |
Czy Ty właściwie sprawdziłeś co Ci podałem w wyniku? Zobacz CO Ci zwraca to zapytanie! masz ID tagu, ilość wystąpień i nazwę. Masz wszystkie dane już. Dlatego użyłem LEFT JOIN z tabelą Tag, by ową nazwę wyciągnąć. Zrób sobie to zapytanie w PhpMyAdmin czy czego tam użuywasz i sprawdź dokładnie zamiast bezmyślnie przepisywać
![]() -------------------- 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
#19
|
|
![]() Grupa: Zarejestrowani Postów: 6 476 Pomógł: 1306 Dołączył: 6.08.2006 Skąd: Kraków Ostrzeżenie: (0%) ![]() ![]() |
btw: nie ma sensu używać LEFT/RIGHT JOIN'a w takich przypadkach (gdy mamy pewność istnienia wszystkich relacji).
|
|
|
![]()
Post
#20
|
|
Grupa: Zarejestrowani Postów: 56 Pomógł: 0 Dołączył: 15.02.2009 Ostrzeżenie: (0%) ![]() ![]() |
Użyłem rozwiazania crozina, tego starego. Nie testowalem Twojego, ale już to naprawiam. Powiedzcie mi tylko czy mam w koncu użyc tego LEFT JOIN czy nie.
|
|
|
![]() ![]() |
![]() |
Wersja Lo-Fi | Aktualny czas: 24.07.2025 - 21:25 |