Avaleht
uus teema   vasta Tarkvara »  Programmeerimine »  MySql: üks keerukas summeerimine märgi kõik teemad loetuks
märgi mitteloetuks
vaata eelmist teemat :: vaata järgmist teemat
Hinnavaatlus :: Foorum :: Uudised :: Ärifoorumid :: HV F1 ennustusvõistlus :: Pangalink :: Telekavad :: HV toote otsing
autor
sõnum Saada viide sõbrale. Teata moderaatorile
otsing:  
kpihus
Kreisi kasutaja
kpihus

liitunud: 14.04.2003




sõnum 21.03.2014 09:40:46 MySql: üks keerukas summeerimine vasta tsitaadiga

Meil on üks tabel, kus me hoiame toodete laoseise. Iga kord kui toodet lisatakse lattu, lisatakse tootele positiivse kogusega kanne. Iga kord kui toodet müüakse, lisatakse negatiivse kogusega kanne. Kui me teeme selektime SUM(amount) toote kohta, saame selle toote laojäägi. Nüüd on tarvis teha üks päring, kus me saame päevade lõikes teada kui palju oli päeva alg saldo, palju tuli juurde, ning palju eemaldati.

Kui meil oleks näiteks selline päring:


SELECT
substring(`ps`.`createdTime`, 1, 10) As Date,
`prod`.`name` AS Name,
`prod`.`id`,
SUM(CASE WHEN `ps`.`amount` >0 THEN `ps`.`amount` ELSE 0 END) as AddAmount,
SUM(CASE WHEN `ps`.`amount` <0 THEN `ps`.`amount` ELSE 0 END) as SaleAmount
FROM `productinstock` as `ps`
JOIN `product` as `prod` ON `ps`.`product` = `prod`.`id`
WHERE `prod`.`id` = 4
GROUP BY substring(`ps`.`createdTime`, 1, 10), `prod`.`id`


Saaksime sellise tulemuse:

Date ,Name ,id ,AddAmount,SaleAmount
2013-11-24,water ,4 ,50 ,0
2014-02-08,water ,4 ,0 ,-3
2014-02-09,water ,4 ,0 ,-1
2014-02-10,water ,4 ,0 ,-16
2014-02-11,water ,4 ,0 ,-1
2014-02-12,water ,4 ,20 ,0
2014-02-18,water ,4 ,0 ,-2
2014-02-19,water ,4 ,0 ,-5
2014-02-22,water ,4 ,48 ,-42

Kõike on peaaegu et ilus, iga päeva lisamised ja müüid on olemas. Kuidas aga teha selliselt, et päevade algsaldod ka kajastatud oleks. Asja teeb keerukamaks veel see, et päringu me limiteerime mingile ajavahemikule (näiteks viimase kuu aja laoliikumised), aga päeva algsaldo peaks olema kõikide kannete summa kuni selle päevani alates aegade algusest.

Proovisin selliselt:


SELECT
substring(`ps`.`createdTime`, 1, 10) As CurrDate,
`prod`.`name` AS Name,
`prod`.`id`,

(SELECT
SUM(`productinstock`.`amount`)
FROM `productinstock`
WHERE (`productinstock`.`createdTime` BETWEEN MIN(`productinstock`.`createdTime`) AND CurrDate) AND `productinstock`.`id` = 4) As originalbal,

SUM(CASE WHEN `ps`.`amount` >0 THEN `ps`.`amount` ELSE 0 END) as AddAmount,
SUM(CASE WHEN `ps`.`amount` <0 THEN `ps`.`amount` ELSE 0 END) as SaleAmount
FROM `productinstock` as `ps`
JOIN `product` as `prod` ON `ps`.`product` = `prod`.`id`
WHERE `prod`.`id` = 4
GROUP BY substring(`ps`.`createdTime`, 1, 10), `prod`.`id`


Aga selle peale sain teateks "invalid use of group function"

Ideid ?
Kommentaarid: 26 loe/lisa Kasutajad arvavad:  :: 0 :: 1 :: 25
tagasi üles
vaata kasutaja infot saada privaatsõnum mine selle kasutaja kodulehele
sosssepp
HV veteran
sosssepp

liitunud: 12.05.2003




sõnum 21.03.2014 11:43:40 vasta tsitaadiga

Aja puudusel hetkel kogu päringusse süvenemata, kas nii ei toimi kui lõpp muuta selliseks?
GROUP BY CurrDate, `prod`.`id`
Kommentaarid: 85 loe/lisa Kasutajad arvavad:  :: 0 :: 2 :: 73
tagasi üles
vaata kasutaja infot saada privaatsõnum
napoleon
Unknown virus
napoleon

liitunud: 08.12.2008



Autoriseeritud ID-kaardiga

sõnum 21.03.2014 11:45:44 vasta tsitaadiga

Proovi midagi sellist:
sql:
  1.  
  2. SELECT ps1.*,
  3. (SELECT
  4. SUM(`productinstock`.`amount`)
  5. FROM `productinstock`
  6. WHERE (`productinstock`.`createdTime` BETWEEN MIN(`productinstock`.`createdTime`) AND CurrDate) AND `productinstock`.`id` = 4) AS originalbal
  7. FROM (
  8. SELECT
  9. substring(`ps`.`createdTime`, 1, 10) AS CurrDate,
  10. `prod`.`name` AS Name,
  11. `prod`.`id`,
  12. SUM(CASE WHEN `ps`.`amount` >0 THEN `ps`.`amount` ELSE 0 END) AS AddAmount,
  13. SUM(CASE WHEN `ps`.`amount` <0 THEN `ps`.`amount` ELSE 0 END) AS SaleAmount
  14. FROM `productinstock` AS `ps`
  15. JOIN `product` AS `prod` ON `ps`.`product` = `prod`.`id`
  16. WHERE `prod`.`id` = 4
  17. GROUP BY substring(`ps`.`createdTime`, 1, 10), `prod`.`id`
  18. ) AS ps1
  19.  

Tõenäoliselt seda alampäringu osa pead natuke kõpitsema kui tahad seda mingi kuupäeva seisuga ja see kuupäev ei ole tänane kuupäev
Kommentaarid: 76 loe/lisa Kasutajad arvavad:  :: 0 :: 0 :: 59
tagasi üles
vaata kasutaja infot saada privaatsõnum
kpihus
Kreisi kasutaja
kpihus

liitunud: 14.04.2003




sõnum 21.03.2014 12:35:09 vasta tsitaadiga

sosssepp kirjutas:
Aja puudusel hetkel kogu päringusse süvenemata, kas nii ei toimi kui lõpp muuta selliseks?
GROUP BY CurrDate, `prod`.`id`


Ei kindlasti mitte icon_smile.gif
Kommentaarid: 26 loe/lisa Kasutajad arvavad:  :: 0 :: 1 :: 25
tagasi üles
vaata kasutaja infot saada privaatsõnum mine selle kasutaja kodulehele
Fukiku
Kreisi kasutaja
Fukiku

liitunud: 06.11.2003




sõnum 21.03.2014 13:05:29 vasta tsitaadiga

Ketserlikult pakuks välja, et äkki oleks siin ikkagi mõistlik lisaks ka laoseisu üle arvet pidada lisaväljal. Seda peaks saama ka olemasoleva loogika külge suhteliselt lihtsasti pookida - lisaväli, mida täidetakse triggeriga näiteks. Siis võib rakendusest kirjete lisamise pool täitsa samaks jääda alustuseks.

Loomulikult tänapäevaste arvutusvõimsuste juures ei ole ilmselt baasiserveril probleemi kogu seda arvutuskäiku iga kord läbi teha, aga kas on mõtet. Pealegi ajaloo kasvades muutub see arvutus siiski ka järjest pikemaks..

_________________
Foxic is just a simple fox
Enne kui sa küsid oma küsimuse - küsi seda vannipardilt! Rangelt soovitatav enne programmeerimise alafoorumisse uue teema tegemist.
Kommentaarid: 2 loe/lisa Kasutajad arvavad:  :: 0 :: 0 :: 2
tagasi üles
vaata kasutaja infot saada privaatsõnum
andresv
HV kasutaja

liitunud: 06.12.2004




sõnum 21.03.2014 18:36:12 vasta tsitaadiga

sql:
  1.  
  2. SELECT date, @total:= IF(@id =id, @total+addamount+saleamount,addamount+saleamount), id, addamount, saleamount, @id:=id FROM sales, (SELECT @total:=0, @id:=0) r ORDER BY id, date ASC
  3.  


tundus töötavat



date   total   id   addamount   saleamount   @id:=id
2013-11-24   50   4   50   0   4
2014-02-08   47   4   0   -3   4
2014-02-09   46   4   0   -1   4
2014-02-10   30   4   0   -16   4
2014-02-11   29   4   0   -1   4
2014-02-12   49   4   20   0   4
2014-02-18   47   4   0   -2   4
2014-02-19   42   4   0   -5   4
2014-02-22   48   4   48   -42   4
2013-11-24   50   6   50   0   6
2014-02-08   47   6   0   -3   6
2014-02-09   26   6   0   -21   6
2014-02-10   20   6   10   -16   6
2014-02-11   19   6   0   -1   6
2014-02-12   39   6   20   0   6
2014-02-18   57   6   20   -2   6
2014-02-19   52   6   0   -5   6
2014-02-22   58   6   48   -42   6


või samas, see ei võimalda teha päringut kindla perioodi peale.

variant on genereerida sellest päringust tabel ja teha sealt limiteeritud päring

create table totalsales as select ...
Kommentaarid: 5 loe/lisa Kasutajad arvavad:  :: 0 :: 0 :: 5
tagasi üles
vaata kasutaja infot saada privaatsõnum
vanavares
HV vaatleja

liitunud: 21.10.2007




sõnum 19.05.2014 23:00:23 vasta tsitaadiga

Alampäringud saab panna lause "from" osasse.
Panin tehted järjest kirja ja selline makaron tuli välja. Võib sisaldada süntaksivigu, aga idee järgi võiks toimida.

select paevasummad.kpv2, product.name, product.id, paevasummad.addamount, paevasummad.saleamount, algsaldod.paeva_algsaldo
from
   -- päevakäive:
   (select ps.product, date(ps.createdTime) kpv2,
   sum(case when ps.amount >0 then ps.amount else 0 end) as addamount,
   sum(case when ps.amount <0 then ps.amount else 0 end) as saleamount
   from productinstock as ps
   group by ps.product, date(ps.createdTime)) as paevasummad
inner join
   -- päeva algsaldo:
   (select sum(ps2.amount) paeva_algsaldo, kandepaev.kpv kpv1, ps2.product
   from productinstock ps2
      inner join (select distinct date(ps1.createdTime) kpv, ps1.product from productinstock ps1) as kandepaev
      on kandepaev.product=ps2.product
   where ps2.createdTime < kandepaev.kpv
   group by kandepaev.kpv, ps2.product
   ) as algsaldod
   on (paevasummad.product=algsaldod.product and paevasummad.kpv2=algsaldod.kpv1)
inner join
   product on product.id=paevasummad.product
where product.id=4
   and paevasummad.kpv2 >= '2014-01-01' -- siia vajadusel mingitsorti intervalli tingimus
;
Kommentaarid: 10 loe/lisa Kasutajad arvavad:  :: 0 :: 0 :: 10
tagasi üles
vaata kasutaja infot saada privaatsõnum
näita postitusi alates eelmisest:   
uus teema   vasta Tarkvara »  Programmeerimine »  MySql: üks keerukas summeerimine
[vaata eelmist teemat] [vaata järgmist teemat]
 lisa lemmikuks
näita foorumit:  
 ignoreeri teemat 
sa ei või postitada uusi teemasid siia foorumisse
sa ei või vastata selle foorumi teemadele
sa ei või muuta oma postitusi selles foorumis
sa ei või kustutada oma postitusi selles foorumis
sa ei või vastata küsitlustele selles foorumis
sa ei saa lisada manuseid selles foorumis
sa võid manuseid alla laadida selles foorumis



Hinnavaatlus ei vastuta foorumis tehtud postituste eest.