列出每日库存的商品,当您拥有的是货物的移动时

时间:2017-05-04 12:58:03

标签: sql oracle

我遇到了问题。我试图从桌子上每天获得库存。

问题在于我只有货物的日期和移动。

所以它基本上就像我从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

4 个答案:

答案 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通过按日期逐inout加/减来返回当天的金额总和。

现在外部查询使用分析函数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