Autor | Zpráva | ||
---|---|---|---|
Soob Profil * |
#1 · Zasláno: 20. 2. 2014, 19:47:59
Ahoj, přemýšlím jak lépe zoptimalizovat tento kód, který vypisuje všechny produkty do tabulky s jejich aktuálním počtem na skladu. Představoval bych si, že to půjde změnšit na jeden nebo 2 SQL dotazy, ale nepřišel jsem na to jak. Zkoušel jsem to prvně přes JOINy v jednom dotazu, ale to počítalo špatně. Abych to trochu osvětlit: Ve vnějším cyklu projedu všechny produkty co existují, uložím u nich počáteční množství a dále ve vnitřních cyklech se mi z každé tabulky jako jsou "prodané produkty z faktur" a "naskladněné zboží" atd... vypočte celkový stav skladu.
<?php $result=mysql_query('SELECT kod, nazev, prichut, id_produkt, mnozstvi AS mnozstvi_pocatecni FROM produkty'); while ($produkt=mysql_fetch_array($result,MYSQL_ASSOC)) { $aktualni_stav = $produkt['mnozstvi_pocatecni']; $result_1=mysql_query('SELECT mnozstvi FROM produkty_na_fakture WHERE id_produkt="'.$produkt['id_produkt'].'" '); $result_2=mysql_query('SELECT mnozstvi FROM produkty_v_balicku_na_fakture WHERE id_produkt="'.$produkt['id_produkt'].'" '); $result_3=mysql_query('SELECT mnozstvi FROM produkty_prijem_zbozi WHERE id_produkt="'.$produkt['id_produkt'].'" '); $result_4=mysql_query('SELECT mnozstvi FROM produkty_v_ubytky_na_skladu WHERE id_produkt="'.$produkt['id_produkt'].'" '); while ($rad=mysql_fetch_array($result_1,MYSQL_ASSOC)) { $aktualni_stav -= $rad['mnozstvi']; } while ($rad=mysql_fetch_array($result_2,MYSQL_ASSOC)) { $aktualni_stav -= $rad['mnozstvi']; } while ($rad=mysql_fetch_array($result_3,MYSQL_ASSOC)) { $aktualni_stav += $rad['mnozstvi']; } while ($rad=mysql_fetch_array($result_4,MYSQL_ASSOC)) { $aktualni_stav -= $rad['mnozstvi']; } ?> <tr> <td><?php echo $produkt['kod']; ?></td> <td><?php echo $produkt['nazev']; ?></td> <td><?php echo $produkt['prichut']; ?></td> <td><?php echo $aktualni_stav; ?></td> <td><?php //echo $xx_dny; ?></td> </tr> <?php } ?> |
||
juriad Profil |
#2 · Zasláno: 20. 2. 2014, 20:14:18
Stačí jediný dotaz. m1 obsahuje veškeré informace o množství (jak kladném, tak záporném), m2 pak už obsahuje konkrétní číslo pro každý produkt. A to celé se přijoinuje k
SELECT p.kod, p.nazev, p.prichut, p.id_produkt, m2.mnozstvi FROM produkty p LEFT JOIN (SELECT id_produkt, SUM(mn) AS mnozstvi FROM (SELECT id_produkt, +mnozstvi AS mn FROM produkty UNION ALL SELECT id_produkt, -mnozstvi AS mn FROM produkty_na_fakture UNION ALL SELECT id_produkt, -mnozstvi AS mn FROM produkty_v_balicku_na_fakture UNION ALL SELECT id_produkt, +mnozstvi AS mn FROM produkty_prijem_zbozi UNION ALL SELECT id_produkt, -mnozstvi AS mn FROM produkty_v_ubytky_na_skladu) m1 GROUP BY m1.id_produkt) m2 ON m2.id_produkt = p.id_produkt Jinou možností je ty další tabulky rovnou příjoinovat: SELECT p.kod, p.nazev, p.prichut, p.id_produkt, p.mnozstvi - COALESCE(pnf.mnozstvi, 0) - COALESCE(pvbnf.mnozstvi, 0) + COALESCE(ppz.mnozstvi, 0) - COALESCE(pvuns.mnozstvi, 0) AS mnozstvi FROM produkty p LEFT JOIN produkty_na_fakture pnf ON pnf.id_produktu = p.id_produktu LEFT JOIN produkty_v_balicku_na_fakture pvbnf ON pvbnf.id_produktu = p.id_produktu LEFT JOIN produkty_prijem_zbozi ppz ON ppz.id_produktu = p.id_produktu LEFT JOIN produkty_v_ubytky_na_skladu pvuns ON pvuns.id_produktu = p.id_produktu |
||
Kcko Profil |
#3 · Zasláno: 20. 2. 2014, 20:37:19
juriad:
To jsi si dal tu práci s vytvořením tabulek nebo to střílíš rovnou z hlavy? |
||
juriad Profil |
#4 · Zasláno: 20. 2. 2014, 20:41:23
Kcko:
Střílím z hlavy, zadání je zřejmé, provedení snad také. Pořád se ten dotaz vejde na jednu stránku. :) Ale opravdu si netroufnu odhadnout, který bude rychlejší. |
||
Soob Profil * |
#5 · Zasláno: 20. 2. 2014, 20:42:45
Boží! Ten první SQL dotaz funguje přesně jak má. Chyběly mi znalosti o UNION ALL. Díky moc.
|
||
Kcko Profil |
#6 · Zasláno: 20. 2. 2014, 20:45:20
juriad:
Tak to klobouček. Tyhle dotazy bych napsal taky, ale musel bych to na něčem zkoušet, takhle z fleku bych to nezvládl. Docela by mne zajímalo, který z nich bude rychlejší, ale jsem líny (unavený) si tvořit tabulky a nějaká data, proto se ptám Sooba, zda-li nechceš někam hodit dump s nějakými testovacími daty? |
||
Časová prodleva: 10 let
|
0