| 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: 12 let
|
|||
0