Autor Zpráva
Soob
Profil *
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
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
juriad:
To jsi si dal tu práci s vytvořením tabulek nebo to střílíš rovnou z hlavy?
juriad
Profil
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 *
Boží! Ten první SQL dotaz funguje přesně jak má. Chyběly mi znalosti o UNION ALL. Díky moc.
Kcko
Profil
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?

Vaše odpověď

Mohlo by se hodit


Prosím používejte diakritiku a interpunkci.

Ochrana proti spamu. Napište prosím číslo dvě-sta čtyřicet-sedm: