我有一个不同产品的运行库存表,记录每次交易后的库存盘点。交易不会每天都发生,因此表中没有每日运行的计数。
我需要为每种产品列出所有日期,以便我可以对一段时间内的计数求和并计算。
库存
DATE ID Qty Count
2014-05-13 123 12 12
2014-05-19 123 -1 11
2014-05-28 123 -1 10
2014-05-29 123 -3 7
2014-05-10 124 5 5
2014-05-15 124 -1 4
2014-05-21 124 -1 3
2014-05-23 124 -3 0
我有一个表格,其中包含加入的日期,但我不确定如何将错过的日期加入多个产品。
我需要查询如下。它需要在选定的时间段内返回计数,但也包括中间的日期。
DATE ID Qty Count
2013-05-01 123 0 0
2013-05-02 123 0 0
2013-05-03 123 0 0
2013-05-04 123 0 0
2013-05-05 123 0 0
2013-05-06 123 0 0
2013-05-07 123 0 0
2013-05-08 123 0 0
2013-05-09 123 0 0
2013-05-10 123 0 0
2013-05-11 123 0 0
2013-05-12 123 0 0
2014-05-13 123 12 12
2013-05-14 123 0 12
2013-05-15 123 0 12
2013-05-16 123 0 12
2013-05-17 123 0 12
2013-05-18 123 0 12
2014-05-19 123 -1 11
2013-05-20 123 0 11
2013-05-21 123 0 11
2013-05-22 123 0 11
2013-05-23 123 0 11
2013-05-24 123 0 11
2013-05-25 123 0 11
2013-05-26 123 0 11
2013-05-27 123 0 11
2014-05-28 123 -1 10
2014-05-29 123 -3 7
2013-05-30 123 0 7
2013-05-31 123 0 7
2013-05-01 124 0 0
2013-05-02 124 0 0
2013-05-03 124 0 0
2013-05-04 124 0 0
2013-05-05 124 0 0
2013-05-06 124 0 0
2013-05-07 124 0 0
2013-05-08 124 0 0
2013-05-09 124 0 0
2014-05-10 124 5 5
2014-05-11 124 0 5
2014-05-12 124 0 5
2014-05-13 124 0 5
2014-05-14 124 0 5
2014-05-15 124 -1 4
2014-05-16 124 0 4
2014-05-17 124 0 4
2014-05-18 124 0 4
2014-05-19 124 0 4
2014-05-20 124 0 4
2014-05-21 124 -1 3
2014-05-22 124 0 3
2014-05-23 124 -3 0
2014-05-24 124 0 0
2014-05-25 124 0 0
2014-05-26 124 0 0
2014-05-27 124 0 0
2014-05-28 124 0 0
2014-05-29 124 0 0
2014-05-30 124 0 0
2014-05-31 124 0 0
答案 0 :(得分:1)
使用inv join inv
构建至少31行并构建一个31天的表。然后加入ids,最后加入原始表格。
select a.d, a.id, a.qty,
if(a.id=@lastid, @count:=@count+a.qty, @count:=a.count) `count`,
@lastid:=a.id _lastid
from (
select a.d, b.id, ifnull(c.qty, 0) qty, ifnull(c.count, 0) `count`
from (
select adddate('2014-05-01', @row) d, @row:=@row+1 i
from inv a
join inv b
join (select @row := 0) c
limit 31) a
join (
select distinct id
from inv) b
left join inv c on a.d = c.date and b.id = c.id
order by b.id, a.d) a
join (select @count := 0, @lastid := 0) b;
答案 1 :(得分:0)
以下是所需的步骤:
所有这些通常都是通过日期的递归CTE,使用KEEP DENSE_RANK函数的所有初始股票的派生表以及用于查看前一记录的LAG函数来实现的。
话虽如此,我建议使用编程语言(Java,C#,PHP,等等)。您只需使用SQL选择原始数据,使用循环并简单地在每个记录库上执行所有processiong。这比构建满足所有需要的非常复杂的查询更方便(和可读)。您可以在SQL中执行此操作,甚至是MySQL;我只是不推荐它。
答案 2 :(得分:0)
我最终用来解决这个问题的SQL使用了@Fabricators答案的组合(这确实是一个正确的答案)和我的编辑。
我最终使用现有表来创建日期行而不是交叉连接。交叉连接在我使用的产品数量方面表现不佳。
SELECT
POSTDATE,
IF(@PROD_ID = PRODUCT_ID, @NEW := 0, @NEW := 1) AS New_Product,
(@PROD_ID := PRODUCT_ID) AS PRODUCT_ID,
QUANTITY,
IF(@NEW = 1, @INVENTORY := QUANTITY, @INVENTORY := @INVENTORY+QUANTITY) AS 'Count'
FROM (
(
SELECT
POSTDATE,
PRODUCT_ID,
QUANTITY
FROM
inventory
)
UNION ALL
(
SELECT
dateslist_sub.TransDate AS POSTDATE,
productlist_sub.PRODUCT_ID,
0 AS QUANTITY,
FROM
(
SELECT
TransDate
FROM
(
SELECT
adddate('2013-05-01', @row) AS TransDate,
@row:=@row+1 i
FROM
any_table,
(SELECT @row := 0) row
) datestable
WHERE
TransDate <= CURDATE()
) dateslist_sub
cross join (
SELECT
PRODUCT_ID
FROM
products_table
ORDER BY
PRODUCT_ID ASC
) productlist_sub
ORDER BY
productlist_sub.PRODUCT_ID ASC,
dateslist_sub.TransDate ASC
)
ORDER BY
PRODUCT_ID ASC,
POSTDATE ASC
) daily_rows_sub