Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

> zliczanie ilość produktów w danej kategorii
DeyV
post
Post #1





Grupa: Zarząd
Postów: 2 277
Pomógł: 6
Dołączył: 27.12.2002
Skąd: Wołów/Wrocław




Hej.
zastanawaiłęm sie, czy nie dać jakiegoś mądrzejeszgo tematu, ale chyba taki jest najbardziej obrazowy.
Akcja toczy się na MySQL, gdzie mamy 2 tabele, produkty i kategorie.
Każdy produkt, poza id i nazwą, ma informacje o tym, do jakiej kategorii należy, oraz 1 pole dodatkowe - flagę, mogąć przyjmować wartość 0 lub 1.
Zadanie polega na tym, by wyświetlić listę kategorii, wraz z 2 liczbami dotyczącymi ilości produktów należących do tej kategorii, osobno jednak licząc produkty o fladze 0, a osobno - 1.
Przykład struktury bazy:
Kod
# Struktura tabeli dla  `kategorie`

CREATE TABLE kategorie (

  id int(11) NOT NULL auto_increment,

  nazwa varchar(100) NOT NULL default '',

  PRIMARY KEY  (id)

) TYPE=MyISAM;

# Zrzut danych tabeli `kategorie`

INSERT INTO kategorie VALUES (1, 'kategoria 1');

INSERT INTO kategorie VALUES (2, 'kategoria 2');

INSERT INTO kategorie VALUES (3, 'kategoria 3');

# --------------------------------------------------------

# Struktura tabeli dla  `produkty`

CREATE TABLE produkty (

  id int(11) NOT NULL auto_increment,

  nazwa varchar(100) NOT NULL default '',

  kat_id int(11) NOT NULL default '0',

  flaga tinyint(4) NOT NULL default '0',

  PRIMARY KEY  (id),

  KEY kat_id (kat_id,flaga)

) TYPE=MyISAM;

# Zrzut danych tabeli `produkty`

INSERT INTO produkty VALUES (1, 'produkt 1', 1, 0);

INSERT INTO produkty VALUES (2, 'produkt 2', 1, 0);

INSERT INTO produkty VALUES (3, 'produkt 3', 1, 1);

INSERT INTO produkty VALUES (4, 'produkt 4', 2, 0);


Moim marzeniem winksmiley.jpg byłoby otrzymać wynik w postaci:

Kod
|id | nazwa         | produkt_flag_0    | produkt_flag_1   |

|---+---------------+-------------------+------------------|

| 1 | kategoria 1   |         2         |          1       |

|---+---------------+-------------------+------------------|

| 2 | kategoria 2   |         1         |          0       |

|---+---------------+-------------------+------------------|

| 3 | kategoria 3   |         0         |          0       |

------------------------------------------------------------


W pierwszej chwili zadanie wydaje się banalne. Ale ... chyba takie nie jest. A zresztą przekonajcie sie sami winksmiley.jpg


--------------------
"Niezależnie od tego, jakie masz osiągnięcia, ktoś Ci pomaga..."
Go to the top of the page
+Quote Post
 
Start new topic
Odpowiedzi (1 - 8)
dragossani
post
Post #2





Grupa: Przyjaciele php.pl
Postów: 398
Pomógł: 0
Dołączył: --
Skąd: Poznań

Ostrzeżenie: (0%)
-----


Nie jest banalne bo wymaga rozgałęzienia agregacji, tzn. dwóch złączeń typu LEFT JOIN do tej samej tabeli, dwóch osobnych poleceń COUNT z osobnymi warunkami (WHERE dotyczący flagi). Jeśli ma być to zrobione w jednym zapytaniu - wymaga mechanizmu subqueries.


--------------------
cease this long, long rest / wake and risk a foul weakness to live / when it all comes down / watch the smoke and bury the past again / sit and think what will come / raise your fears and cast them all away
Go to the top of the page
+Quote Post
uboottd
post
Post #3





Grupa: Zarejestrowani
Postów: 384
Pomógł: 0
Dołączył: 3.04.2003
Skąd: Chorzow

Ostrzeżenie: (0%)
-----


BANAL!!

[sql:1:e88c7ba0a7]
SELECT kategorie.id, kategorie.nazwa,
SUM(if(flag=0,1,0)) as produkt_flag_0,
SUM(if(flag=1,1,0)) as produkt_flag_1
FROM kategorie LEFT JOIN produkty ON kat_id = kategorie.id
GROUP BY kategorie.id;
[/sql:1:e88c7ba0a7]
IF jest tu uzyty tylko dla ilustracji jesli pole flag mogloby przyjmowac dowolne wartosci, jeszcze prostsza wersje dla podanych warunkow zadania zaraz zapoda adwol.

Lub dla ciekawosci na dwoch sklejeniach:

[sql:1:e88c7ba0a7]
SELECT kategorie.id, kategorie.nazwa,
SUM(if(p1.flag=0,1,0)) as produkt_flag_0,
SUM(ifnull(p2.flag,0)) as produkt_flag_1
FROM kategorie
LEFT JOIN produkty as p1 ON p1.kat_id = kategorie.id AND flag = 0
LEFT JOIN produkty as p2 ON p2.kat_id = kategorie.id AND flag = 1
GROUP BY kategorie.id;
[/sql:1:e88c7ba0a7]


Jak na razie spotkalem dokladnie jedna bardzo zagrzybiona sytuacje gdzie nie jestem do konca pewien czy uda sie to zrobic jednym zapytaniem bez podzapytan (dalem to zadanie w http://forum.php.pl/viewtopic.php?t=2093 )
Go to the top of the page
+Quote Post
adwol
post
Post #4





Grupa: Zarejestrowani
Postów: 691
Pomógł: 0
Dołączył: 6.08.2003

Ostrzeżenie: (0%)
-----


Cytat
Hej.  
zastanawaiłęm sie, czy nie dać jakiegoś mądrzejeszgo tematu, ale chyba taki jest najbardziej obrazowy.  
Akcja toczy się na MySQL, gdzie mamy 2 tabele, produkty i kategorie.  
Każdy produkt, poza id i nazwą, ma informacje o tym, do jakiej kategorii należy, oraz 1 pole dodatkowe - flagę, mogąć przyjmować wartość 0 lub 1.  
Zadanie polega na tym, by wyświetlić listę kategorii, wraz z 2 liczbami dotyczącymi ilości produktów należących do tej kategorii, osobno jednak licząc produkty o fladze 0, a osobno - 1.

[sql:1:7c3dd86fdb]select kategorie.nazwa, ifnull(sum(1-produkty.flaga),0) as produkt_flag_0, ifnull(sum(produkty.flaga),0) as produkt_flag_1 from kategorie left join produkty on kat_id=kategorie.id group by kategorie.id;
[/sql:1:7c3dd86fdb]
Go to the top of the page
+Quote Post
DeyV
post
Post #5





Grupa: Zarząd
Postów: 2 277
Pomógł: 6
Dołączył: 27.12.2002
Skąd: Wołów/Wrocław




Cytat
jeszcze prostsza wersje dla podanych warunkow zadania zaraz zapoda adwol.

Prorok, czy co? ;:)

A na powaźnie - dzięki, (i widać z tego, że o SQL jest znacznie potęzniejszy, niż się zazwyczaj wydaje)

Choć nie rozumiem, po co w warunku adwola jest sprawdzanie IFNULL :/


--------------------
"Niezależnie od tego, jakie masz osiągnięcia, ktoś Ci pomaga..."
Go to the top of the page
+Quote Post
adwol
post
Post #6





Grupa: Zarejestrowani
Postów: 691
Pomógł: 0
Dołączył: 6.08.2003

Ostrzeżenie: (0%)
-----


Cytat
Choć nie rozumiem, po co w warunku adwola jest sprawdzanie IFNULL :/

Usuń to i sprawdź na danych które podałeś to się dowiesz. :wink:
Go to the top of the page
+Quote Post
DeyV
post
Post #7





Grupa: Zarząd
Postów: 2 277
Pomógł: 6
Dołączył: 27.12.2002
Skąd: Wołów/Wrocław




Cytat
Usuń to i sprawdź na danych które podałeś to się dowiesz. :wink:

Zapytanie
Kod
SELECT kategorie.nazwa,

sum( 1 - produkty.flaga )  AS produkt_flag_0,

sum( produkty.flaga )  AS produkt_flag_1

FROM kategorie

LEFT  JOIN produkty ON kat_id = kategorie.id

GROUP  BY kategorie.id

daje dokładnie to samo (przynajmniej na tych danych) Mogę więc prosić o objaśnienie? winksmiley.jpg


--------------------
"Niezależnie od tego, jakie masz osiągnięcia, ktoś Ci pomaga..."
Go to the top of the page
+Quote Post
adwol
post
Post #8





Grupa: Zarejestrowani
Postów: 691
Pomógł: 0
Dołączył: 6.08.2003

Ostrzeżenie: (0%)
-----


Cytat
Mogę więc prosić o objaśnienie? winksmiley.jpg

Dla tych danych które podałeś:
Kod
mysql> select kategorie.nazwa, sum(1-produkty.flaga) as produkt_flag_0, sum(prod

ukty.flaga) as produkt_flag_1 from kategorie left join produkty on kat_id=katego

rie.id group by kategorie.id;

+-------------+----------------+----------------+

| nazwa       | produkt_flag_0 | produkt_flag_1 |

+-------------+----------------+----------------+

| kategoria 1 |              2 |              1 |

| kategoria 2 |              1 |              0 |

| kategoria 3 |           NULL |           NULL |

+-------------+----------------+----------------+

Kod
mysql> select kategorie.nazwa, ifnull(sum(1-produkty.flaga),0) as produkt_flag_0

, ifnull(sum(produkty.flaga),0) as produkt_flag_1 from kategorie left join produ

kty on kat_id=kategorie.id group by kategorie.id;

+-------------+----------------+----------------+

| nazwa       | produkt_flag_0 | produkt_flag_1 |

+-------------+----------------+----------------+

| kategoria 1 |              2 |              1 |

| kategoria 2 |              1 |              0 |

| kategoria 3 |              0 |              0 |

+-------------+----------------+----------------+

Po prostu left join spowoduje że puste kategorie będą miały nulle zamiast zer, a z tego co widziałem to chciałeś zera. W phpie po wyciągnięciu wyników takiego zapytania w miejsce nulla dostaniesz ciąg pusty co może mieć znaczenie.
Go to the top of the page
+Quote Post
dragossani
post
Post #9





Grupa: Przyjaciele php.pl
Postów: 398
Pomógł: 0
Dołączył: --
Skąd: Poznań

Ostrzeżenie: (0%)
-----


Jestem pod wrażeniem tej agregacji po IF'ach. Niezłe. smile.gif


--------------------
cease this long, long rest / wake and risk a foul weakness to live / when it all comes down / watch the smoke and bury the past again / sit and think what will come / raise your fears and cast them all away
Go to the top of the page
+Quote Post

Reply to this topicStart new topic
1 Użytkowników czyta ten temat (1 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Aktualny czas: 21.08.2025 - 07:37