有条件 summing/subtracting 数量

Conditionally summing/subtracting quantities

我有两个 table(PS_BU_ITEMS_INV APS_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