有条件 summing/subtracting 数量
Conditionally summing/subtracting quantities
我有两个 table(PS_BU_ITEMS_INV A
和 PS_TRANSACTION_INV B
)用于库存项目管理。 PS_BU_ITEMS_INV A
包含一个字段,其中包含项目 A.QTY_ONHAND
的当前现有数量。 table PS_TRANSACTION_INV B
是一项交易 table,它列出了减少或增加 [=19] 中的 A.QTY_ONHAND
值的所有交易(装运、消耗等) =] table 来自名为 B.QTY_BASE
的字段。
B.QTY_BASE
列中存储的值都是正数,因此我必须查看另一个名为 B.TRANSACTION_GROUP
的列来确定 B.QTY_BASE
中的数量是否应该添加或减去当前 A.QTY_ONHAND
值。
下面是每个 tables
的示例数据
PS_BU_ITEMS_INV:
SELECT BUSINESS_UNIT, INV_ITEM_ID, QTY_ONHAND, DT_TIMESTAMP
FROM PS_BU_ITEMS_INV
WHERE INV_ITEM_ID = '1'
AND BUSINESS_UNIT = '11MMS'
结果:
BUSINESS_UNIT INV_ITEM_ID QTY_ONHAND DT_TIMESTAMP
11MMS 1 16.0000 2018-09-11 08:12:46.827
PS_TRANSATION_INV:
SELECT BUSINESS_UNIT, INV_ITEM_ID, TRANSACTION_DATE,
TRANSACTION_GROUP, QTY_BASE, DT_TIMESTAMP
FROM PS_TRANSACTION_INV
WHERE INV_ITEM_ID = '1'
AND BUSINESS_UNIT = '11MMS'
ORDER BY DT_TIMESTAMP DESC
结果:
假设我想确定 9 月 4 日的 QTY_ONHAND
值;我将从 PS_BU_ITEMS_INV
table 中获取当前 QTY_ONHAND
值(在本例中为 16.0 并添加(总和)(来自 PS_TRANSACTION_INV
)相关的 QTY_BASE
值使用 Transaction_Group(s) '030', and '036'
(这些是物品消耗)并使用 TRANSATION_GROUP = '020'
减去数量
所以我应该有截至 2018 年 9 月 4 日的 ON_QTY
计算:16 + (SUM OF -->(14+2+2+5+2+1+2+10- 24+10+10-24) = 26
到目前为止,我已经将以下查询写到 SUM
数量(对于今天(当前日期)和硬编码日期(9/4/ 18 在这个例子中),但我正在努力如何添加某种类型的 CASE WHEN
或条件 IF
语句,如果 TRANSACTION_GROUP
是 030 或 036 然后将值加在一起,如果 TRANSACTION_GROUP
是 020,则减去这些值。由于缺少条件减法,查询目前无法从 2018 年 9 月 4 日得到正确的 ON_HAND_QTY。
SELECT A.INV_ITEM_ID, A.BUSINESS_UNIT, A.QTY_ONHAND, A.DT_TIMESTAMP,
DATEADD(MINUTE, DATEDIFF(MINUTE, 0, B.DT_TIMESTAMP), 0) AS TRANSACTION_DT,
(A.QTY_ONHAND + (SELECT SUM(BB.QTY_BASE)
FROM PS_TRANSACTION_INV BB WHERE BB.TRANSACTION_DATE
BETWEEN '2018-09-04' AND GETDATE() AND BB.INV_ITEM_ID
= '1'
AND BB.BUSINESS_UNIT = '11MMS'
AND BB.BUSINESS_UNIT = B.BUSINESS_UNIT AND BB.INV_ITEM_ID
= B.INV_ITEM_ID)) AS QTY_ONHAND_AS_OF_DT
FROM PS_BU_ITEMS_INV A
LEFT OUTER JOIN PS_TRANSACTION_INV B ON B.BUSINESS_UNIT
= A.BUSINESS_UNIT
AND B.INV_ITEM_ID = A.INV_ITEM_ID
AND DATEADD(MINUTE, DATEDIFF(MINUTE, 0, A.DT_TIMESTAMP), 0) =
DATEADD(MINUTE, DATEDIFF(MINUTE, 0, B.DT_TIMESTAMP), 0)
WHERE B.INV_ITEM_ID = '1'
AND B.BUSINESS_UNIT = '11MMS'
我想要一些类似这样的效果:
SELECT
A.INV_ITEM_ID, A.BUSINESS_UNIT, A.QTY_ONHAND, A.DT_TIMESTAMP,
DATEADD(MINUTE, DATEDIFF(MINUTE, 0, B.DT_TIMESTAMP), 0) AS TRANSACTION_DT,
(A.QTY_ONHAND + (CASE WHEN B.TRANSACTION_GROUP IN ('030', '036') THEN
SUM(B.QTY_BASE)
WHEN B.TRANSACTION_GROUP = '020' THEN
SUM(-B.QTY_BASE) END AS ON_HANDS_AS_OF_DATE ) )
FROM PS_BU_ITEMS_INV A
LEFT OUTER JOIN PS_TRANSACTION_INV B ON B.BUSINESS_UNIT
= A.BUSINESS_UNIT
AND B.INV_ITEM_ID = A.INV_ITEM_ID
AND DATEADD(MINUTE, DATEDIFF(MINUTE, 0, A.DT_TIMESTAMP), 0) =
DATEADD(MINUTE, DATEDIFF(MINUTE, 0, B.DT_TIMESTAMP), 0)
WHERE B.INV_ITEM_ID = '1'
AND B.BUSINESS_UNIT = '11MMS'
AND B.TRANSACTION_DATE BETWEEN '2018-09-04' AND GETDATE()
虽然这个查询不起作用。感谢任何反馈。
编辑:
这是我编辑的 SQL,但它 return 是错误的有条件计算的现有价值。我什至在日期范围的 CASE WHEN
中添加了附加条件,但它仍然没有 return 正确的值 (26)。
SELECT
A.INV_ITEM_ID, A.BUSINESS_UNIT, A.QTY_ONHAND, A.DT_TIMESTAMP,
DATEADD(MINUTE, DATEDIFF(MINUTE, 0, B.DT_TIMESTAMP), 0) AS TRANSACTION_DT,
(A.QTY_ONHAND + SUM(CASE WHEN B.TRANSACTION_GROUP IN ('030', '036') --AND B.TRANSACTION_DATE BETWEEN '2018-09-04' AND GETDATE()
THEN (B.QTY_BASE)
WHEN B.TRANSACTION_GROUP = '020' --AND B.TRANSACTION_DATE BETWEEN '2018-09-04' AND GETDATE()
THEN (-B.QTY_BASE) END ) )
FROM PS_BU_ITEMS_INV A
LEFT OUTER JOIN PS_TRANSACTION_INV B ON B.BUSINESS_UNIT
= A.BUSINESS_UNIT
AND B.INV_ITEM_ID = A.INV_ITEM_ID
AND DATEADD(MINUTE, DATEDIFF(MINUTE, 0, A.DT_TIMESTAMP), 0) =
DATEADD(MINUTE, DATEDIFF(MINUTE, 0, B.DT_TIMESTAMP), 0)
WHERE B.INV_ITEM_ID = '1'
AND B.BUSINESS_UNIT = '11MMS'
AND B.TRANSACTION_DATE BETWEEN '2018-09-04' AND GETDATE()
GROUP BY A.INV_ITEM_ID, A.BUSINESS_UNIT, A.QTY_ONHAND, A.DT_TIMESTAMP, DATEADD(MINUTE, DATEDIFF(MINUTE, 0, B.DT_TIMESTAMP), 0)
编辑 2:
我很好奇为什么这个查询得到我正确的数量计数 (26)(为了简化,我硬编码了 A.QTY_ONHAND 中的值)
SELECT (32 + SUM(CASE WHEN B.TRANSACTION_GROUP IN ('030', '036') --AND B.TRANSACTION_DATE BETWEEN '2018-09-04' AND GETDATE() THEN
THEN (B.QTY_BASE)
WHEN B.TRANSACTION_GROUP = '020' --AND B.TRANSACTION_DATE BETWEEN '2018-09-04' AND GETDATE()
THEN (-B.QTY_BASE) END ) )
FROM PS_TRANSACTION_INV B
WHERE B.INV_ITEM_ID = '1'
AND B.BUSINESS_UNIT = '11MMS'
AND B.TRANSACTION_DATE BETWEEN '2018-09-04' AND GETDATE()
然而下面的查询(使用相同的条件逻辑)得到了不同的(不正确的)数量?
SELECT
A.INV_ITEM_ID, A.BUSINESS_UNIT, A.QTY_ONHAND, A.DT_TIMESTAMP,
DATEADD(MINUTE, DATEDIFF(MINUTE, 0, B.DT_TIMESTAMP), 0) AS TRANSACTION_DT,
(A.QTY_ONHAND + SUM(CASE WHEN B.TRANSACTION_GROUP IN ('030', '036') --AND B.TRANSACTION_DATE BETWEEN '2018-09-04' AND GETDATE() THEN
THEN B.QTY_BASE
WHEN B.TRANSACTION_GROUP = '020' --AND B.TRANSACTION_DATE BETWEEN '2018-09-04' AND GETDATE()
THEN -B.QTY_BASE END ) )
FROM PS_BU_ITEMS_INV A
LEFT OUTER JOIN PS_TRANSACTION_INV B ON B.BUSINESS_UNIT
= A.BUSINESS_UNIT
AND B.INV_ITEM_ID = A.INV_ITEM_ID
AND DATEADD(MINUTE, DATEDIFF(MINUTE, 0, A.DT_TIMESTAMP), 0) =
DATEADD(MINUTE, DATEDIFF(MINUTE, 0, B.DT_TIMESTAMP), 0)
WHERE B.INV_ITEM_ID = '1'
AND B.BUSINESS_UNIT = '11MMS'
AND B.TRANSACTION_DATE BETWEEN '2018-09-04' AND GETDATE()
GROUP BY A.INV_ITEM_ID, A.BUSINESS_UNIT, A.QTY_ONHAND, A.DT_TIMESTAMP, DATEADD(MINUTE, DATEDIFF(MINUTE, 0, B.DT_TIMESTAMP), 0)
我不会调试您的确切查询。不过,您可以在下面看到如何有条件地对值求和并将其减去当前值,这样您就可以回到过去并找到原始数量:
假设您的数据是:
create table ps_bu_items_inv (
business_unit varchar(20),
inv_item_id int,
qty_onhand decimal(12, 8),
dt_timestamp datetime
);
insert into ps_bu_items_inv (business_unit, inv_item_id, qty_onhand, dt_timestamp)
values ('11MMS', 1, 16.0, '2018-09-11 08:12:46.827');
create table ps_transaction_inv (
business_unit varchar(20),
inv_item_id int,
transaction_date date,
transaction_group varchar(6),
qty_base decimal(12, 8),
dt_timestamp datetime
);
insert into ps_transaction_inv (business_unit, inv_item_id, transaction_date, transaction_group, qty_base, dt_timestamp)
values ('11MMS', 1, '2018-09-11', '036', 14, '2018-09-11 12:34:56');
insert into ps_transaction_inv (business_unit, inv_item_id, transaction_date, transaction_group, qty_base, dt_timestamp)
values ('11MMS', 1, '2018-09-11', '020', 24, '2018-09-11 12:34:56');
insert into ps_transaction_inv (business_unit, inv_item_id, transaction_date, transaction_group, qty_base, dt_timestamp)
values ('11MMS', 1, '2018-09-11', '030', 6, '2018-09-11 12:34:56');
查询应类似于:
select a.*, b.*, (a.qty_onhand - b.change) as original_qty
from ps_bu_items_inv a
join (
select
inv_item_id,
sum( -- here's the conditional sum
case when transaction_group <> '020' then -qty_base else qty_base end
) as change
from ps_transaction_inv
where transaction_date between '2018-09-01' and '2018-09-11'
group by inv_item_id
) b on a.inv_item_id = b.inv_item_id
结果:
business_unit inv_item_id qty_onhand dt_timestamp inv_item_id change original_qty
------------- ----------- ---------- ------------ ----------- ------ ------------
11MMS 1 16 2018-09-11 1 4 12
如您所见,原始数量显示为 12
。即当前 16
减去变化 4
。在这种情况下,"changes" 计算为:
-14 +24 -6 = +4
我有两个 table(PS_BU_ITEMS_INV A
和 PS_TRANSACTION_INV B
)用于库存项目管理。 PS_BU_ITEMS_INV A
包含一个字段,其中包含项目 A.QTY_ONHAND
的当前现有数量。 table PS_TRANSACTION_INV B
是一项交易 table,它列出了减少或增加 [=19] 中的 A.QTY_ONHAND
值的所有交易(装运、消耗等) =] table 来自名为 B.QTY_BASE
的字段。
B.QTY_BASE
列中存储的值都是正数,因此我必须查看另一个名为 B.TRANSACTION_GROUP
的列来确定 B.QTY_BASE
中的数量是否应该添加或减去当前 A.QTY_ONHAND
值。
下面是每个 tables
的示例数据PS_BU_ITEMS_INV:
SELECT BUSINESS_UNIT, INV_ITEM_ID, QTY_ONHAND, DT_TIMESTAMP
FROM PS_BU_ITEMS_INV
WHERE INV_ITEM_ID = '1'
AND BUSINESS_UNIT = '11MMS'
结果:
BUSINESS_UNIT INV_ITEM_ID QTY_ONHAND DT_TIMESTAMP
11MMS 1 16.0000 2018-09-11 08:12:46.827
PS_TRANSATION_INV:
SELECT BUSINESS_UNIT, INV_ITEM_ID, TRANSACTION_DATE,
TRANSACTION_GROUP, QTY_BASE, DT_TIMESTAMP
FROM PS_TRANSACTION_INV
WHERE INV_ITEM_ID = '1'
AND BUSINESS_UNIT = '11MMS'
ORDER BY DT_TIMESTAMP DESC
结果:
假设我想确定 9 月 4 日的 QTY_ONHAND
值;我将从 PS_BU_ITEMS_INV
table 中获取当前 QTY_ONHAND
值(在本例中为 16.0 并添加(总和)(来自 PS_TRANSACTION_INV
)相关的 QTY_BASE
值使用 Transaction_Group(s) '030', and '036'
(这些是物品消耗)并使用 TRANSATION_GROUP = '020'
所以我应该有截至 2018 年 9 月 4 日的 ON_QTY
计算:16 + (SUM OF -->(14+2+2+5+2+1+2+10- 24+10+10-24) = 26
到目前为止,我已经将以下查询写到 SUM
数量(对于今天(当前日期)和硬编码日期(9/4/ 18 在这个例子中),但我正在努力如何添加某种类型的 CASE WHEN
或条件 IF
语句,如果 TRANSACTION_GROUP
是 030 或 036 然后将值加在一起,如果 TRANSACTION_GROUP
是 020,则减去这些值。由于缺少条件减法,查询目前无法从 2018 年 9 月 4 日得到正确的 ON_HAND_QTY。
SELECT A.INV_ITEM_ID, A.BUSINESS_UNIT, A.QTY_ONHAND, A.DT_TIMESTAMP,
DATEADD(MINUTE, DATEDIFF(MINUTE, 0, B.DT_TIMESTAMP), 0) AS TRANSACTION_DT,
(A.QTY_ONHAND + (SELECT SUM(BB.QTY_BASE)
FROM PS_TRANSACTION_INV BB WHERE BB.TRANSACTION_DATE
BETWEEN '2018-09-04' AND GETDATE() AND BB.INV_ITEM_ID
= '1'
AND BB.BUSINESS_UNIT = '11MMS'
AND BB.BUSINESS_UNIT = B.BUSINESS_UNIT AND BB.INV_ITEM_ID
= B.INV_ITEM_ID)) AS QTY_ONHAND_AS_OF_DT
FROM PS_BU_ITEMS_INV A
LEFT OUTER JOIN PS_TRANSACTION_INV B ON B.BUSINESS_UNIT
= A.BUSINESS_UNIT
AND B.INV_ITEM_ID = A.INV_ITEM_ID
AND DATEADD(MINUTE, DATEDIFF(MINUTE, 0, A.DT_TIMESTAMP), 0) =
DATEADD(MINUTE, DATEDIFF(MINUTE, 0, B.DT_TIMESTAMP), 0)
WHERE B.INV_ITEM_ID = '1'
AND B.BUSINESS_UNIT = '11MMS'
我想要一些类似这样的效果:
SELECT
A.INV_ITEM_ID, A.BUSINESS_UNIT, A.QTY_ONHAND, A.DT_TIMESTAMP,
DATEADD(MINUTE, DATEDIFF(MINUTE, 0, B.DT_TIMESTAMP), 0) AS TRANSACTION_DT,
(A.QTY_ONHAND + (CASE WHEN B.TRANSACTION_GROUP IN ('030', '036') THEN
SUM(B.QTY_BASE)
WHEN B.TRANSACTION_GROUP = '020' THEN
SUM(-B.QTY_BASE) END AS ON_HANDS_AS_OF_DATE ) )
FROM PS_BU_ITEMS_INV A
LEFT OUTER JOIN PS_TRANSACTION_INV B ON B.BUSINESS_UNIT
= A.BUSINESS_UNIT
AND B.INV_ITEM_ID = A.INV_ITEM_ID
AND DATEADD(MINUTE, DATEDIFF(MINUTE, 0, A.DT_TIMESTAMP), 0) =
DATEADD(MINUTE, DATEDIFF(MINUTE, 0, B.DT_TIMESTAMP), 0)
WHERE B.INV_ITEM_ID = '1'
AND B.BUSINESS_UNIT = '11MMS'
AND B.TRANSACTION_DATE BETWEEN '2018-09-04' AND GETDATE()
虽然这个查询不起作用。感谢任何反馈。
编辑:
这是我编辑的 SQL,但它 return 是错误的有条件计算的现有价值。我什至在日期范围的 CASE WHEN
中添加了附加条件,但它仍然没有 return 正确的值 (26)。
SELECT
A.INV_ITEM_ID, A.BUSINESS_UNIT, A.QTY_ONHAND, A.DT_TIMESTAMP,
DATEADD(MINUTE, DATEDIFF(MINUTE, 0, B.DT_TIMESTAMP), 0) AS TRANSACTION_DT,
(A.QTY_ONHAND + SUM(CASE WHEN B.TRANSACTION_GROUP IN ('030', '036') --AND B.TRANSACTION_DATE BETWEEN '2018-09-04' AND GETDATE()
THEN (B.QTY_BASE)
WHEN B.TRANSACTION_GROUP = '020' --AND B.TRANSACTION_DATE BETWEEN '2018-09-04' AND GETDATE()
THEN (-B.QTY_BASE) END ) )
FROM PS_BU_ITEMS_INV A
LEFT OUTER JOIN PS_TRANSACTION_INV B ON B.BUSINESS_UNIT
= A.BUSINESS_UNIT
AND B.INV_ITEM_ID = A.INV_ITEM_ID
AND DATEADD(MINUTE, DATEDIFF(MINUTE, 0, A.DT_TIMESTAMP), 0) =
DATEADD(MINUTE, DATEDIFF(MINUTE, 0, B.DT_TIMESTAMP), 0)
WHERE B.INV_ITEM_ID = '1'
AND B.BUSINESS_UNIT = '11MMS'
AND B.TRANSACTION_DATE BETWEEN '2018-09-04' AND GETDATE()
GROUP BY A.INV_ITEM_ID, A.BUSINESS_UNIT, A.QTY_ONHAND, A.DT_TIMESTAMP, DATEADD(MINUTE, DATEDIFF(MINUTE, 0, B.DT_TIMESTAMP), 0)
编辑 2:
我很好奇为什么这个查询得到我正确的数量计数 (26)(为了简化,我硬编码了 A.QTY_ONHAND 中的值)
SELECT (32 + SUM(CASE WHEN B.TRANSACTION_GROUP IN ('030', '036') --AND B.TRANSACTION_DATE BETWEEN '2018-09-04' AND GETDATE() THEN
THEN (B.QTY_BASE)
WHEN B.TRANSACTION_GROUP = '020' --AND B.TRANSACTION_DATE BETWEEN '2018-09-04' AND GETDATE()
THEN (-B.QTY_BASE) END ) )
FROM PS_TRANSACTION_INV B
WHERE B.INV_ITEM_ID = '1'
AND B.BUSINESS_UNIT = '11MMS'
AND B.TRANSACTION_DATE BETWEEN '2018-09-04' AND GETDATE()
然而下面的查询(使用相同的条件逻辑)得到了不同的(不正确的)数量?
SELECT
A.INV_ITEM_ID, A.BUSINESS_UNIT, A.QTY_ONHAND, A.DT_TIMESTAMP,
DATEADD(MINUTE, DATEDIFF(MINUTE, 0, B.DT_TIMESTAMP), 0) AS TRANSACTION_DT,
(A.QTY_ONHAND + SUM(CASE WHEN B.TRANSACTION_GROUP IN ('030', '036') --AND B.TRANSACTION_DATE BETWEEN '2018-09-04' AND GETDATE() THEN
THEN B.QTY_BASE
WHEN B.TRANSACTION_GROUP = '020' --AND B.TRANSACTION_DATE BETWEEN '2018-09-04' AND GETDATE()
THEN -B.QTY_BASE END ) )
FROM PS_BU_ITEMS_INV A
LEFT OUTER JOIN PS_TRANSACTION_INV B ON B.BUSINESS_UNIT
= A.BUSINESS_UNIT
AND B.INV_ITEM_ID = A.INV_ITEM_ID
AND DATEADD(MINUTE, DATEDIFF(MINUTE, 0, A.DT_TIMESTAMP), 0) =
DATEADD(MINUTE, DATEDIFF(MINUTE, 0, B.DT_TIMESTAMP), 0)
WHERE B.INV_ITEM_ID = '1'
AND B.BUSINESS_UNIT = '11MMS'
AND B.TRANSACTION_DATE BETWEEN '2018-09-04' AND GETDATE()
GROUP BY A.INV_ITEM_ID, A.BUSINESS_UNIT, A.QTY_ONHAND, A.DT_TIMESTAMP, DATEADD(MINUTE, DATEDIFF(MINUTE, 0, B.DT_TIMESTAMP), 0)
我不会调试您的确切查询。不过,您可以在下面看到如何有条件地对值求和并将其减去当前值,这样您就可以回到过去并找到原始数量:
假设您的数据是:
create table ps_bu_items_inv (
business_unit varchar(20),
inv_item_id int,
qty_onhand decimal(12, 8),
dt_timestamp datetime
);
insert into ps_bu_items_inv (business_unit, inv_item_id, qty_onhand, dt_timestamp)
values ('11MMS', 1, 16.0, '2018-09-11 08:12:46.827');
create table ps_transaction_inv (
business_unit varchar(20),
inv_item_id int,
transaction_date date,
transaction_group varchar(6),
qty_base decimal(12, 8),
dt_timestamp datetime
);
insert into ps_transaction_inv (business_unit, inv_item_id, transaction_date, transaction_group, qty_base, dt_timestamp)
values ('11MMS', 1, '2018-09-11', '036', 14, '2018-09-11 12:34:56');
insert into ps_transaction_inv (business_unit, inv_item_id, transaction_date, transaction_group, qty_base, dt_timestamp)
values ('11MMS', 1, '2018-09-11', '020', 24, '2018-09-11 12:34:56');
insert into ps_transaction_inv (business_unit, inv_item_id, transaction_date, transaction_group, qty_base, dt_timestamp)
values ('11MMS', 1, '2018-09-11', '030', 6, '2018-09-11 12:34:56');
查询应类似于:
select a.*, b.*, (a.qty_onhand - b.change) as original_qty
from ps_bu_items_inv a
join (
select
inv_item_id,
sum( -- here's the conditional sum
case when transaction_group <> '020' then -qty_base else qty_base end
) as change
from ps_transaction_inv
where transaction_date between '2018-09-01' and '2018-09-11'
group by inv_item_id
) b on a.inv_item_id = b.inv_item_id
结果:
business_unit inv_item_id qty_onhand dt_timestamp inv_item_id change original_qty
------------- ----------- ---------- ------------ ----------- ------ ------------
11MMS 1 16 2018-09-11 1 4 12
如您所见,原始数量显示为 12
。即当前 16
减去变化 4
。在这种情况下,"changes" 计算为:
-14 +24 -6 = +4