Autor Zpráva
Toník
Profil *
Zdravím,

chci se zeptat, zda by někdo nedokázal poradit s optimalizací SQL příkazu.
Vyhledávám z tabulky a objednávek TOP produkty (nejprodávanější produkty) - jenže produkty mají i rodiče...Tedy...

V příkazu je zapojena tabulka - order (objednavka), products (produkt), products_lang (jazykove informace),
A potřebuji zjistit nejprodávanější produkty (za danou dobu), ovšem s tím, že produkty mají varianty, a já chci pouze hlavní produkt (parent_id=0) ale aby v něm byly započítané prodeje variant (tedy celkově)


order => info objednávky => na datum je index
order_products => id/order_id/product_id/ ...na order_id i product_id jsou indexy
products => id, parent_id, active, enable_buy...
products_lang => id, product_id, lang_id, name, text, title => id je primary, product_id ma index, lang_id ma index

Příkaz funguje, ale je pomalý (procházi se všechny produkty => v nich počet objednávek a v nich znova ještě id variant)
Zkoušel jsem to projít naopak - skrze produkty objednávek, ale tam zase nevím, jak zapojit parent_id

SELECT pr.id, pr.active, pr.enable_buy, prl.name, prl.urlname, (
    SELECT SUM(count) FROM  order_products objpr  
        LEFT JOIN order obj ON objpr.order_id=obj.id
        WHERE obj.date>...INT DATUM... AND ( objpr.product_id=pr.id OR objpr.product_id IN ( SELECT id FROM products WHERE parent_id=pr.id ) )
) as totalOrders 
FROM products pr
LEFT JOIN products_lang prl ON pr.id=prl.product_id
WHERE prl.lang_id=1 AND pr.parent_id=0
ORDER BY totalOrders DESC LIMIT 30
Kajman
Profil
Je tam více zanoření na rodiče než jedno? Pokud je více, tak máte verzi databáze podporující rekurzívní dotazy?
Toník
Profil *
nevím teď jak to myslíte ?
Kajman
Profil
To byste měl vědět Vy, jestli to víte nebo nevíte. Ale tipuji, že nevíte.

Může být produkt, který má rodiče, který má rodiče?

Funguje Vám dotaz, na který skočí odkaz?
Toník
Profil *
Už to chápu.

Je pouze hlavní produkt a jeho varianty (jestli je to už kombinace variant, to je jedno, to je zvlášť třeba varianta barva bílá vel. XL, další varianta barva bíla vel. XS atd.) a každé id produktu má zase napojené tabulky stock (sklad) aj...

Jak jsem psal, můj dotaz funguje, jen není 2x rychlý, i když někdy skočí hned, jindy zase třeba 10s..ale to je asi o cache.
Kajman
Profil
Můžete zkusit něco jako toto, ale netuším, jestli to bude rychlejší.
SELECT p.id,
       p.active,
       p.enable_buy,
       prl.name,
       prl.urlname,
       t.totalorders
FROM   (SELECT Coalesce(par.id, pr.id) id,
               Sum(count)              totalorders
        FROM   `order` obj
               JOIN order_products op
                 ON op.order_id = obj.id
               JOIN products pr
                 ON op.product_id = pr.id
               LEFT JOIN products par
                      ON pr.parent_id = par.id
        WHERE  obj.date >= '2021-01-01'
        GROUP  BY Coalesce(par.id, pr.id)) t
       JOIN products p
         ON t.id = p.id
       JOIN products_lang prl
         ON p.id = prl.product_id
WHERE  prl.lang_id = 1
ORDER  BY totalorders DESC
LIMIT  30  
Toník
Profil *
Panejo, vypadá to že to běží teď super rychle :-))
Nejsem specialista na DB právě.

Dík moc, nemám problém to zaplatit, možná bych potřeboval častěji vypomoct, máte nějaký kontakt?
Toník
Profil *
Kajman:

Rovnou bych se zeptal ješte, mám podobný příkaz, který mi vytáhné top zákazníky místo produktů a mám to takto, jen mi nevytahuje reálné data (resp vyhodí uživatele ale bludy..
je to to stejné, je tam počítá SUM( cena produktu * počet kusů ) jako totalPay a COUNT na počet objednávek

SELECT u.*,
t.totalOrders,
t.totalPay
FROM ( 

SELECT usr.id id, COUNT(obj.id) totalOrders, SUM(op.product_price * op.count) totalPay 
FROM  shop_order obj 
JOIN shop_users usr ON usr.id = obj.user_id 
JOIN shop_order_products op ON op.order_id = obj.id 
WHERE  obj.pay_id>0 
GROUP BY usr.id

) t
JOIN shop_users u ON t.id = u.id
WHERE  u.active=1 AND u.rights=0
ORDER  BY totalOrders DESC
LIMIT  30
Kajman
Profil
Tam stačí asi
COUNT(DISTINCT obj.id)
jinak to počítá řádky objednávek a ne objednávky.
Toník
Profil *
Jo, takto je to OK, jen mě nevychází ani totalPay :O lítají mí tam částky různě
a v tabulce order_products je product_price i count (počet ks) kterým se to snažím násobit - jen nevím jestli to takto jde, vychází mi třeba o 5 tis méně než je součet objednávek
Kajman
Profil
To si musíte najít sám, v čem se to liší. Jestli např. nejsou v samostatném sloupci recyklační poplatky nebo něco takového. Prostě si data z jedné objednávky nebo u jednoho zákazníka, kde se to liší, vypište detailně a hledejte nesoulad.
Toník
Profil *
jsem **** ...zapoměl sem tam připočítat cenu platby a dopravy, počítám jen produkty, dík za pomoc :/
a jak jsem psal, rád se spojím kdybych potřeboval vymyslet příkazy nebo optimalizovat u klientů :)

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:

0