我的任务是为库存管理应用程序创建查询功能。
我已经创建了查询,它将在其中生成
temporaryTable
,如下所示:id 项目 | 上一个日期 | 最新日期 |
---|---|---|
10 | 2023-01-03 | 2023-04-01 |
15 | 2023-04-01 | 2023-06-01 |
我有一个表来存储交易
tableTransaction
,如下所示:
id 项目 | 数量 | 最后数量 | 交易日期 |
---|---|---|---|
10 | 0 | 10 | 2023-01-01 |
10 | 10 | 10 | 2023-03-04 |
10 | -5 | 5 | 2023-03-05 |
10 | 100 | 105 | 2023-03-06 |
15 | 0 | 0 | 2023-01-01 |
15 | 100 | 100 | 2023-03-01 |
15 | 35 | 135 | 2023-04-02 |
15 | -15 | 120 | 2023-05-01 |
想问一下如何才能得到这个想要的结果? 得到
lastQty
的previousDate
为beginningBalance
,lastQty
的latestDate
为endingBalance
; totalInput
; totalOutput
对于 idItem
中 tableTranscation
和 previousDate
之间的每个 latestDate
(标准基于之前的 temporaryTable
)。
期望的结果:
id 项目 | 之前日期的开始余额 | 上一个日期 | 最新日期的期末余额 | 期末余额 | 总输入 | 总输出 |
---|---|---|---|---|---|---|
10 | 10 | 2023-01-03 | 105 | 2023-04-01 | 110 | 5 |
15 | 100 | 2023-04-01 | 120 | 2023-06-01 | 35 | 15 |
感谢您的宝贵时间,我愿意接受数据库设计的任何更改。干杯。
您需要按日期计算余额以及总投入、总产出,然后将它们连接在一起。
DROP TABLE IF EXISTS #temporaryTable
CREATE TABLE #temporaryTable (
idItem int,
previousDate date,
latestDate date
);
INSERT INTO #temporaryTable (idItem, previousDate, latestDate)
VALUES
('10','2023-01-03','2023-04-01')
,('15','2023-04-01','2023-06-01')
DROP TABLE IF EXISTS #tableTransaction
CREATE TABLE #tableTransaction (
idItem int,
qty int,
lastQty int,
transactionDate date
);
INSERT INTO #tableTransaction (idItem, qty, lastQty, transactionDate)
VALUES
('10','0','10','2023-01-01')
,('10','10','10','2023-03-04')
,('10','-5','5','2023-03-05')
,('10','100','105','2023-03-06')
,('15','0','0','2023-01-01')
,('15','100','100','2023-03-01')
,('15','35','135','2023-04-02')
,('15','-15','120','2023-05-01')
; WITH beginningBalancePerDate AS (
SELECT temporaryTable.idItem, a.previousDate, tableTransaction.lastQty BalancePerDate
, ROW_NUMBER() OVER (PARTITION BY temporaryTable.idItem, a.previousDate ORDER BY tableTransaction.transactionDate desc ) RowNumber
FROM #tableTransaction tableTransaction
inner join #temporaryTable temporaryTable
on tableTransaction.idItem = temporaryTable.idItem
cross apply (
SELECT temporaryTable.previousDate
UNION
SELECT temporaryTable.latestDate
) a
WHERE tableTransaction.transactionDate <= a.previousDate
), sumInput AS (
SELECT temporaryTable.idItem, temporaryTable.previousDate, temporaryTable.latestDate,
SUM(CASE WHEN tableTransaction.qty > 0 THEN tableTransaction.qty ELSE 0 END ) totalInput,
SUM(CASE WHEN tableTransaction.qty < 0 THEN tableTransaction.qty * (-1) ELSE 0 END ) totalOutput
FROM #tableTransaction tableTransaction
inner join #temporaryTable temporaryTable
on tableTransaction.idItem = temporaryTable.idItem
WHERE tableTransaction.transactionDate <= temporaryTable.latestDate
AND tableTransaction.transactionDate > temporaryTable.previousDate
GROUP BY temporaryTable.idItem, temporaryTable.previousDate, temporaryTable.latestDate
)
SELECT temporaryTable.idItem
, preDate.BalancePerDate beginningBalanceperPreviousDate
, temporaryTable.previousDate
, nextDate.BalancePerDate beginningBalanceperLatestDate
, temporaryTable.latestDate endingBalance -- strange column name
, sumInput.totalInput
, sumInput.totalOutput
FROM #temporaryTable temporaryTable
LEFT JOIN sumInput
ON temporaryTable.idItem = sumInput.idItem
AND temporaryTable.previousDate = sumInput.previousDate
AND temporaryTable.latestDate = sumInput.latestDate
LEFT JOIN beginningBalancePerDate preDate
ON temporaryTable.idItem = preDate.idItem
AND temporaryTable.previousDate = preDate.previousDate
AND preDate.RowNumber = 1
LEFT JOIN beginningBalancePerDate nextDate
ON temporaryTable.idItem = nextDate.idItem
AND temporaryTable.latestDate = nextDate.previousDate
AND nextDate.RowNumber = 1