Sql 有条件地求和/减去数量

Sql 有条件地求和/减去数量,sql,sql-server-2014,Sql,Sql Server 2014,我有两个表(PS\u BU\u ITEMS\u INV A和PS\u TRANSACTION\u INV B)用于库存项目管理PS_BU_ITEMS_INV A包含一个字段,其中当前am item的现存量A.quaty_ONHAND。表PS\u TRANSACTION\u INV B是一个事务表,列出了PS\u BU\u ITEMS\u INV a表中名为B.QTY\u BASE字段中减少或增加a.QTY\u现存量值的所有事务(装运、消耗等) 存储在B.QTY\u BASE列中的值都是正数,因此

我有两个表(
PS\u BU\u ITEMS\u INV A
PS\u TRANSACTION\u INV B
)用于库存项目管理<代码>PS_BU_ITEMS_INV A包含一个字段,其中当前am item的现存量
A.quaty_ONHAND
。表
PS\u TRANSACTION\u INV B
是一个事务表,列出了
PS\u BU\u ITEMS\u INV a
表中名为
B.QTY\u BASE
字段中减少或增加
a.QTY\u现存量
值的所有事务(装运、消耗等)

存储在
B.QTY\u BASE
列中的值都是正数,因此我必须查看另一个名为
B.TRANSACTION\u GROUP
的列,以确定
B.QTY\u BASE
中的数量是否应从当前
A.QTY\u现存值中添加或减去

下面是每个表中的示例数据

PS\u BU\u项目库存:

  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
 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
结果:

  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
 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
PS\U交易\U投资:

  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
 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
结果:

  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
 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日的现存量值是多少;我将从
PS\u BU\u ITEMS\u INV
表中获取当前
QTY\u ONHAND
值(在本例中为16.0,并添加(总和)(从
PS\u TRANSACTION\u INV
)与交易组
'030'和'036'相关的
QTY\u BASE
值(这些是项目消耗)用
transaction\u GROUP='020'减去数量

因此,对于2018年9月4日的
ON_数量计算,我应该有16+(14+2+2+5+2+1+2+10-24+10+10-24之和)=26

到目前为止,我已经编写了以下查询以
SUM
数量(对于今天(当前日期)和硬编码日期(本例中为9/4/18)之间发生的交易的030和036(正)数量),但我很难在
或条件
IF
语句中添加某种类型的
CASE,如果
事务组
为030或036,则将值相加,如果
事务组
为020,则减去值。查询目前无法从9中获得正确的手头数量/4/18因为缺少条件减法

  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()
但此查询不起作用。欢迎提供任何反馈

编辑:

  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
 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
这是我编辑过的SQL,但是它返回的是错误的按手计算的条件值。我甚至在日期范围的
中添加了附加条件,但它仍然没有返回正确的值(26)

编辑2:

  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
 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
我很好奇为什么这个查询会得到正确的数量计数(26)(为了简化,我硬编码了A.QTY\u的值)

但是下面的查询(使用相同的条件逻辑)得到了不同(不正确)的数量

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
如您所见,原始数量显示为
12
。即当前数量
16
减去变化
4
。在这种情况下,“变化”计算为:

-14 +24 -6 = +4

使用条件求和:
sum(结束时为CASE)
。我认为编辑2的问题在于分组。分组时,您包括了表B中的列,这可能会产生不同的子组。感谢您的反馈。我用我的任务编辑了上面的帖子,但它仍然没有得到正确的计算值。是否考虑我的查询是否需要修改?计算字段(CASE-WHEN)由于某种原因似乎忽略了我在查询中定义的日期条件……是的,它应该忽略
WHERE
子句中的任何条件,并将对所选的所有行求和。但是,它将按您想要的方式求和。我再次编辑了文章(编辑上面的2)当我试图理解为什么两个查询产生不同的结果时?