我遇到了问题。我试图从桌子上每天获得库存。
问题在于我只有货物的日期和移动。
所以它基本上就像我从2001年01.01开始有一个初始的iventory,从那天开始我只有动作。像进出货物一样。 例如:
initial inventory: 1000 pcs
01.01.2001: 500 leave the stock - 150 incoming goods.
01.02.2001: 100 leave the stock - 400 incoming goods.
....
为了获得特定日期的库存,您必须发送以下查询:
SELECT SUM(amount)
FROM stock
WHERE date <= <date>
表格如下:
Date Type Amount
---------- ---- ------
12.31.2000 in 1000
01.01.2001 in 150
01.01.2001 out 500
01.02.2001 in 400
01.02.2001 out 150
01.03.2001 in 300
01.03.2001 out 50
我想要的结果是:
Date Amount
---------- ------
31.12.2000 1000
01.01.2001 650
01.02.2001 900
01.03.2001 1150
问题是一次为每个日期获取不同的行。
了解库存情况很简单:
select sum(amount)-(select sum(amount) From stock where type = 'out' and date <='01.03.2001')
From Stock
where Type = 'in'
and date <= 01.03.2001
答案 0 :(得分:1)
你能试试吗?
SELECT SUM(CASE WHEN TYPE = 'in' THEN +AMOUNT WHEN TYPE='out' THEN -AMOUNT ELSE 0 END) AS AMOUNT_TOT
FROM stock
WHERE DATE <= '2001-01-01'
或者,如果它更具可读性:
SELECT SUM(AMOUNT * CASE WHEN TYPE = 'in' THEN 1 WHEN TYPE='out' THEN -1 ELSE 0 END) AS AMOUNT_TOT
FROM stock
WHERE DATE <= '2001-01-03'
评论后更新(如果您需要一个月的所有日期,使用计数日期表和使用此查询的左连接很容易做到):
SELECT DATE,SUM(AMOUNT_TOT) OVER(ORDER BY DATE) AS DAY_BY_DAY
FROM (
SELECT DATE, SUM(AMOUNT * CASE WHEN TYPE = 'in' THEN 1 WHEN TYPE='out' THEN -1 ELSE 0 END) AS AMOUNT_TOT
FROM stock
GROUP BY DATE
) A
答案 1 :(得分:1)
试试这个
select t.dt,
sum(curr_stock) over ( order by dt) as stock1
from
( select dt,
sum(case when type='out' then -1 * amount
else amount end
) as curr_stock
from stock
group by dt
) t
说明:内部查询t
通过按日期逐in
或out
加/减来返回当天的金额总和。
现在外部查询使用分析函数sum() over (partition by
来进行累积求和。
工作样本
with stock(dt,Type,Amount) as (
select to_date('12.31.2000','MM.DD.YYYY'),'in',1000 from dual union all
select to_date('01.01.2001','MM.DD.YYYY'),'in', 150 from dual union all
select to_date('01.01.2001','MM.DD.YYYY'),'out', 500 from dual union all
select to_date('01.02.2001','MM.DD.YYYY'),'in', 400 from dual union all
select to_date('01.02.2001','MM.DD.YYYY'),'out', 150 from dual union all
select to_date('01.03.2001','MM.DD.YYYY'),'in', 300 from dual union all
select to_date('01.03.2001','MM.DD.YYYY'),'out', 50 from dual)
select t.dt,
sum(curr_stock) over ( order by dt) as stock1
from
( select dt,
sum(case when type='out' then -1 * amount
else amount end
) as curr_stock
from stock
group by dt
) t
答案 2 :(得分:1)
Oracle安装程序:
CREATE TABLE stock ( "Date", Type, Amount ) AS
SELECT DATE '2000-12-31', 'in', 1000 FROM DUAL UNION ALL
SELECT DATE '2001-01-01', 'in', 150 FROM DUAL UNION ALL
SELECT DATE '2001-01-01', 'out', 500 FROM DUAL UNION ALL
SELECT DATE '2001-01-02', 'in', 400 FROM DUAL UNION ALL
SELECT DATE '2001-01-02', 'out', 150 FROM DUAL UNION ALL
SELECT DATE '2001-01-03', 'in', 300 FROM DUAL UNION ALL
SELECT DATE '2001-01-04', 'out', 50 FROM DUAL;
<强>查询强>:
SELECT DISTINCT
"Date",
SUM( CASE TYPE WHEN 'in' THEN Amount ELSE -Amount END ) OVER ( order by "Date" ) AS total
FROM stock
ORDER BY "Date"
<强>输出强>:
Date TOTAL
---------- -----
2000-12-31 1000
2001-01-01 650
2001-01-02 900
2001-01-03 1150
答案 3 :(得分:0)
我现在无法测试它,但这应该可以解决问题:
SELECT INCOMMING.in - OUTGOING.out
FROM
(
SELECT SUM(amount) AS 'in'
FROM stock
WHERE date <= <date> AND type = 'in'
) INCOMMING
JOIN
(
SELECT SUM(amount) AS 'out'
FROM stock
WHERE date <= <date> AND type = 'out'
) OUTGOING
ON
1=1
修改强>
在您对etsas回答发表评论后,我了解到您希望在一个查询中查看所有可能的条目。我现在无法对其进行测试,但这应该是可能的:
SELECT
STOCKDATE.date,
(
SELECT
INCOMMING.in - OUTGOING.out AS 'dailyCount'
FROM
(
SELECT SUM(amount) AS 'in'
FROM stock
WHERE date <= STOCKDATE.date AND type = 'in'
) INCOMMING
JOIN
(
SELECT SUM(amount) AS 'out'
FROM stock
WHERE date <= STOCKDATE.date AND type = 'out'
) OUTGOING
ON
1=1
)
FROM stock STOCKDATE