TwojePC.pl © 2001 - 2024
|
|
A R C H I W A L N A W I A D O M O Ś Ć |
|
|
|
[algorytmy/sql] 1. w jakis sposób najprościej ustalać kolejność? 2. jak posortować , kubazzz 12/11/09 17:10 1. mamy kategorię, w której mamy np. 15 pozycji, cokolwiek, teksty, produkty, nieistotne, ważne że jest 15 wpisów w bazie.
Jak najprosćiej wprowadzić system ustawiania kolejności wyświetlania. Na zasadzie przesuwania wyżej/niżej.
Wymyśliłem, żeby zrobić to tak, że każdy wpis ma pole "pozycja" i początkowo są te wpisy ponumerowane w jakiś tam sposób, niech będzie zgodnie z kolejnością alfabetyczną.
A potem, gdy ktoś kliknie "przesuń wyżej", to o ile to nie jest najwyższa pozycja w danej grupie, to zwiększa pozycję tego artykułu o 1, a tego który miał jeden więcej, zmniejsza o 1.
Problem tylko, że mi tu wychodzi dosyć sporo operacji bo w tabeli są artykuły ze wszystkich kategorii, a dla każdej kategorii jest inna kolejność, a co jeśli artykuł zmieni kategorię.
Nie mam pomysłu na proste zapytania.
2. Załóżmy, że w bazie jest lista produktów, które mają pole "nazwa" i "producent".
Chcę wyświetlić wszystkie produkty, na zasadzie takiej, żebym miał pogrupowane wg producenta, a potem wg innej cechy [np kolejność, cena, etc].
Wszystko niby proste, robimy GROUP BY, ale kurde jak zorganizować wyświetlanie wyników potem, żebym łatwo mógł w pętli zrobić coś takiego:
<h3>producent1</h3>
<ol>
<li>produkt a
...
<li>produkt e
</ol>
<h3>producent2</h3>
<ol>
<li>produkt f
...
<li>produkt j
</ol>
etc.
Chodzi o to, żeby przed pierwszym produktem danego producenta wiedzieć jaki to jest i potem przed każdym następnym też mieć identyfikator.
Przyznaję, że nie mam czasu żeby przerobić cały materiał i dojść do tego samemu, a mam braki i nie potrafię zgrabnie robić takich masowych zapytań SQL, łatwo się gubię;)
3. Powiązane też - ile zapytań na jedno wyświetlenie strony to dużo zapytań?
Bo zrobiłem coś takiego, że lista kategorii wyświetla się w pętli:
na zasadzie
SELECT * FROM categories ORDER BY name ASC
foreach($id=result->id)
{
SELECT * FROM produkty WHERE category->id
foreach(produkt)
{wyświetl produkt}
}
To działa super, ale jest w sumie dużo zapytań (aktualnie jest 5 kategorii) i wydaje mi się, ze to nie jest "dobra praktyka".
Z góry dziękuję za pomoc.SM-S908 - zapytania zlozone... , xmac 12/11/09 17:26
w sekcji from musisz dodac dwie tabele, ktore zlaczysz po odpowiednim w sekcji where
sortowac pozniej mozesz po dowolnej kolumnie z dowolnej tabeli
np. select t1.col_1, t2.col_x
from tabela1 t1, tabela2 t2
where
t1.id = t2.id
order by
t1.col_a asc, t2.col_b descdual&mobile power
XMAC - no dobra, ale jak potem te wyniki , kubazzz 12/11/09 17:32
przechwycić i przerobić?
Jakiś prosty przykład?SM-S908 - w sensie, jak to potem na obiekty przerzucić , kubazzz 12/11/09 17:56
Jeśli mam selecty z dwóch tabel, to jak zadziała coś takiego
if($result = $baza->query($query))
{
while($obj = $result->fetch_object())
}SM-S908
- hmm , _oLo_1984 12/11/09 18:13
$res = mysql_query('select p.nazwa as produkt_nazwa, p.id as produkt_id, c.id as category_id, c.nazwa as category_name from category as c left join produkty as p on p.fk_id_category = c.ID order by c.nazwa asc, p.nazwa asc') or die(mysql_error());
$categories = array();
while ($row = mysql_fetch_array($res)){
$category_id = $row['category_id'];
if (!isset($categories[$category_id]))
{
$categories[$category_id] = array('name' => $row['category_name'], 'products' => array());
}
if (!empty($row['produkt_nazwa']))
{
$categories[$category_id]['products'][] = array('name' => $row['produkt_nazwa'], 'id'=>$row['produkt_id']);
}
}
print_r($categories);
potem zwykły foreach w foreach i masz pięknie co chcesz. Wiesz o co chodzi ?awake - zaraz przetworzę , kubazzz 12/11/09 18:18
i powinienem dojść powoli o co chodzi, na wszelki wypadek może mi ktoś po kroku wytłumaczyć kolejne elementy tego zapytania.SM-S908 - w sumie to samo , _oLo_1984 12/11/09 18:25
co Ci podał xmac, masz dwie tabele, gdzie w tabeli produkty przechowujesz klucz do kategori (fk_id_category). Wyciągasz wszystkie pozycje z kategorii, dołączasz produkty (left join), sortujesz po nazwach. Potem przy while wypełniasz nową tablicę. Pola sobie pozamieniasz na takie jak masz u siebie. Zalety to jedno zapytanie i logiczna tablica do iteracji.awake - inaczej mówiąc, przepiszmy to na moją składnię , kubazzz 12/11/09 18:45
mam tabele
kategorie : c_id, c_name
produkty: p_id, p_cat_id, p_name, p_price
gubie się na tym joinie, patrzyłem na reference tutaj http://dev.mysql.com/doc/refman/5.0/en/select.html i jeszcze mam mętlik
ja do tej pory robiłem proste zapytania typu
"SELECT * FROM categories ORDER BY name ASC"
albo
"SELECT p_name, p_price FROM products ORDER BY p_subcategory ASC, p_id ASC"
w momencie kiedy dodane jest zapytanie z drugiej tabeli, to te przecinki i ordery nabierają nowego znaczenia.SM-S908 - no niestety , _oLo_1984 12/11/09 19:01
musisz iść krok dalej. Może wklej najpierw w phpmyadminie (lub czymś takim) to zapytanie, zapoznaj się i przeanalizuj wyniki, pokombinuj z sortowaniem, poeksperymentuj. No i niestety twardo manual. A co do Twojego przypadku to coś takiego będzie (o ile się gdzieś nie walłem):
$res = mysql_query('select p.p_name, p.p_id, p.p_price, c.c_id, c.c_name from category as c left join produkty as p on p.p_cat_id = c.c_id order by c.c_name asc, p.p_name asc') or die(mysql_error());
$categories = array();
while ($row = mysql_fetch_array($res))
{
$c_id = $row['c_id'];
if (!isset($categories[$c_id]))
{
$categories[$c_id] = array('name' => $row['c_name'], 'products' => array());
}
if (!empty($row['p_name']))
{
$categories[$c_id]['products'][] = array('name' => $row['p_name'], 'id'=>$row['p_id'], 'cena'=>$row['p_price']);
}
}
te same nazwy więc bez bólu.awake - jak to wrzuciłem w myadmin to wybrałby mi wszystkie kategorie , kubazzz 12/11/09 19:34
i dopasowal produkty po ID, czyli
wzial kategorie z ID 12 i do tego dopasowal produkt z ID 12.
wyszla krotka tabela, ktorej polowa pol to NULL.
Mialo na odwrot dzialac, czyli do każdego produktu dopasować nazwę kategorii.
Powoli już łapię o co chodzi, ale jeszcze nie całkiem.SM-S908 - przerobiłem tak jak wydawało mi się, że będzie ok , kubazzz 12/11/09 19:44
coś takiego:
SELECT p.p_name, p.p_id, p.p_price, c.id, c.name
FROM products AS p
RIGHT JOIN subcategories AS c ON c.id = p.p_subcategory
ORDER BY p.p_id
LIMIT 0 , 120
subkategorii jest w sumie 23, produktów 9 [bo baza jest prawie pusta].
To zapytanie wywaliło mi 27 wierszy, z czego pierwsze 21 ma wszystkie pola "p." jako NULL i jakieś nie wiem jak wybrane kategorie z nazwa, a potem następne 6 wierszy to produkty z p.id od 4 do 9, w sumie szesc produktow i dopasowane do tego kategorie.
WTF?SM-S908 - ok, już jedno wiem, ale drugiego nie wiem , kubazzz 12/11/09 19:54
wiem czemu zaczęło produkty od czwartego, bo produkty z id od 1 do 3 miały numer subkategorii, której już nie ma.
Ale czemu te 21 NULL NULL NULL wyszło, to jeszcze nie weim.SM-S908
- ad 3) To nie jest dobra praktyka , bwana 12/11/09 21:34
Na Boga, zrób join-a."you don't need your smile when I cut
your throat" - join'a jeszcze nie ogarniam w pełni , kubazzz 12/11/09 21:44
nie zwraca mi w pełni tego co chcę, prawdopodobnie nie rozumiem tego jak działa.
to co mi xmac napisał, to już rozpracowałem.
Tylko wtedy tak - dane dostaje w ramach jednej większej kwerendy, ale robi się duży array w php - to będzie szybsze? [w teorii, bo w praktyce i tak to się robi w ułamkach sekundy]SM-S908 - hmm , recydywista 12/11/09 23:18
tu jest nieźle join wytłumaczony
http://www.w3schools.com/SQl/default.asp
żadne rocket science, uwierz miComputers are useless. They can only
give you
answers. - dużo diakuju , kubazzz 13/11/09 01:39
lepiej niż na dev.mysql.com, tam jest burdel potworny, nie idzie rozczytać, a na w3schools wszystko logicznie, że też zapomniałem o tej stronce.
już wiem, czemu mój RIGHT JOIN źle działa;)SM-S908
- bez urazy, ale faktycznie widać, że trochę nie ogarniasz SQL-a , bwana 13/11/09 07:34
próbujesz używać go w taki sposób, jakby tabele bazy to były "takie lepsze pliki" bo mające "wbudowane sortowanie i filtrowanie". Słowem, cały czas widać, że programujesz algorytmicznie, natomiast SQL to język deklaratywny.
Spróbuj trochę wysiłku włożyć w poznanie teorii relacyjnych baz danych oraz pisania zapytań w SQL, zaoszczędzi Ci to wielu błędów, wyważania otwartych drzwi, rozbijania problemu na szereg małych zapytań i spinania ich kodem PHP (bo nie wiesz, jak zapytać bazę "jednym zdaniem"). Szczególnie teraz, kiedy jesteś najwyraźniej świeży w temacie i jeszcze nie zdążyłeś nabrać wielu złych nawyków;-)"you don't need your smile when I cut
your throat"
- na boga , Wedrowiec 13/11/09 10:19
nie rób join'ów :D"Widziałem podręczniki
Gdzie jest czarno na białym
Że jesteście po**bani" - na Boga , bwana 14/11/09 09:51
Dlaczego? Postaw bazę na jednej maszynie, serwer aplikacji na drugiej i zobaczysz jaki jest narzut na przekazanie zapytania do wykonania z procesu aplikacji do procesu bazy. Nie upieram się, że tak jest faktycznie w przypadku Apache/PHP - MySQL, lecz _zazwyczaj_ tak jest.
Oczywiście zdarza mi się, że piszę jakąś funkcję na Oracle i okazuje się, że od joina szybciej działa otwarcie kursora a potem w pętli po tym kursorze otwieranie innego kursora. Za to kiedy taki kod działa produkcyjnie, to zabiera nieco więcej zasobów. W przypadku aplikacji webowej efekt wielodostępu jest jeszcze większy, więc, na Boga, użyj joina - powrót króla:-D"you don't need your smile when I cut
your throat" - takie tam doświadczenia - , Wedrowiec 15/11/09 14:36
90% przypadków użycia joina w kodzie jakie widziałem to była masakra. Zwykły where działał duuużo szybciej i zwracał rzeczywiście potrzebne dane a nie te potrzebne + 90% to śmieci.
Ale to jak ze wszystkim - da się zrobić dobrze jedną i drugą metodą, tak samo spieprzyć ;)"Widziałem podręczniki
Gdzie jest czarno na białym
Że jesteście po**bani"
|
|
|
|
|
All rights reserved ® Copyright and Design 2001-2024, TwojePC.PL |
|
|
|
|