praegune kellaaeg 16.06.2024 10:15:53
|
Hinnavaatlus
:: Foorum
:: Uudised
:: Ärifoorumid
:: HV F1 ennustusvõistlus
:: Pangalink
:: Telekavad
:: HV toote otsing
|
|
autor |
sõnum |
|
kpihus
Kreisi kasutaja
liitunud: 14.04.2003
|
21.03.2014 09:40:46
MySql: üks keerukas summeerimine |
|
|
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 |
|
|
sosssepp
HV veteran
liitunud: 12.05.2003
|
21.03.2014 11:43:40
|
|
|
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 |
|
|
napoleon
Unknown virus
liitunud: 08.12.2008
|
21.03.2014 11:45:44
|
|
|
Proovi midagi sellist:
sql:
|
SELECT ps1.*, (SELECT SUM(`productinstock`.`amount`) FROM `productinstock` WHERE (`productinstock`.`createdTime` BETWEEN MIN(`productinstock`.`createdTime`) AND CurrDate) AND `productinstock`.`id` = 4) AS originalbal FROM ( SELECT substring(`ps`.`createdTime`, 1, 10) AS CurrDate, `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` ) AS ps1
|
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 |
|
|
kpihus
Kreisi kasutaja
liitunud: 14.04.2003
|
21.03.2014 12:35:09
|
|
|
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
|
|
Kommentaarid: 26 loe/lisa |
Kasutajad arvavad: |
|
:: |
0 :: |
1 :: |
25 |
|
tagasi üles |
|
|
Fukiku
Kreisi kasutaja
liitunud: 06.11.2003
|
21.03.2014 13:05:29
|
|
|
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 |
|
|
andresv
HV kasutaja
liitunud: 06.12.2004
|
21.03.2014 18:36:12
|
|
|
sql:
|
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
|
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 |
|
|
vanavares
HV vaatleja
liitunud: 21.10.2007
|
19.05.2014 23:00:23
|
|
|
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 |
|
|
|
lisa lemmikuks |
|
|
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.
|