[英]SQL Join Inventory Count Table to Date table
我有一個運行中的不同產品的庫存表,該表記錄每筆交易后的庫存數量。 交易並非每天都會發生,因此該表沒有每日運行的計數。
我需要列出每種產品的所有日期,以便可以對一段時間內的計數求和並取平均值。
庫存
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
使用inv join inv
可以建立至少31行並構造一個31天的表。 然后加入id,最后加入原始表。
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;
這是需要的步驟:
通常使用日期的遞歸CTE,最多使用KEEP DENSE_RANK函數的所有初始存貨的派生表以及使用LAG函數查看先前記錄的方法來實現所有這些目的。
話雖如此,我建議改用編程語言(Java,C#,PHP等)。 您只需使用SQL選擇原始數據,使用循環,然后簡單地對每個記錄進行所有處理。 這比構建一個非常復雜的查詢來完成所有需要的操作要方便得多(而且可讀性強)。 您可以在SQL中執行此操作,甚至可以在MySQL中執行; 我只是不推薦。
我最終用來解決此問題的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
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.