基于运行总计返回的计数值的访问或T-SQL查询

时间:2012-07-17 15:46:19

标签: sql sql-server database ms-access

我正在使用在我们的数据库中存储为报告/视图的库存分类帐。导出时,它看起来像这样:

Tran Type         Txn Date     Item     Quantity
Opening Balance   6/30/12      Item1     4
Opening Balance   6/30/12      Item2     7
Shipping          7/14/12      Item2    -1
Opening Balance   6/30/12      Item3     3
Shipping          7/2/12       Item3    -1
Opening Balance   6/30/12      Item4     5
Shipping          7/3/12       Item4    -1
Shipping          7/3/12       Item4    -1
Shipping          7/3/12       Item4    -1
Shipping          7/5/12       Item4    -1
Shipping          7/5/12       Item4    -1
Receiving         7/9/12       Item4    10

在导出之前,它不包含那些根据导出期间生成的“期初余额”条目。

我们正在尝试跟踪每个项目在给定时间内缺货的天数。第一阶段是按项目创建运行总计,这是我之前通过Excel中的数据透视表进行的。从那里开始,我需要保持灵活,动态的计数,每个项目的库存数量为0(基于月,季度或年)。最初,我曾希望通过数据透视表来计算这个数量,而我turned to superuser's help for that.不幸的是,通过excel进行这类工作似乎可能是违反直觉的,所以我在这里提出我的问题。

我在Access和SQL Server方面只有新手经验。我在Oracle和PL / SQL方面进行了一些轻松的正式培训,但这是几年前的事了。可能会为此添加另一个复杂功能,我无法在系统后端写入或永久保存任何内容(即使我有权限)。

到目前为止,我只想出一个T-SQL语句来按项目创建运行总计:

Select 
 TxnDate,
    Quantity,
        Item,
    (SELECT Sum(Quantity)
    FROM DATABASE.dbo.InventoryLedger as D1
    WHERE D1.TxnDate <= D0.TxnDate AND D1.Item = D0.Item) as balance
    FROM DATABASE.dbo.InventoryLedger as D0
    where Item = 'Item4' and TxnDate >= 2012-07-01

此后我迷路了。我不知道是否应该进行某种计数,或者找到一种方法来减去一个项目达到0数量然后再次收到之间的日期。我不确定如何根据已经计算的余额列添加另一个聚合或计算列,我甚至不确定如何翻译此查询,以便它将与我的相同数据的Access文件一起使用。我接受Access或T-SQL格式的解决方案;我渴望真正学习T-SQL,而能够在Access中执行计数会让我链接数据库并使我更容易生成直接报告。

我也很好奇是否有一种简单的方法可以查询每天每件商品的库存水平?我想这只是使用相同的确切数据来计算,所以它可能只是浪费时间和空间,对吗?

我很感激任何帮助,伙计们。我一直在努力想出一个现在已经有几个月测量缺货的解决方案了,这是我最接近的。感谢。

1 个答案:

答案 0 :(得分:1)

使用正确的一组窗口/分析功能可以更轻松。但我有一个想法,可能有用。

首先,您可以使用自联接获得累积金额。

然后,还要对此进行自我加入以获得下一个非零暨,并使用group by来获取下一条记录的最小日期:

with tcum as (
     select t.txnDate, t.Item, t.quantity, sum(tprev.quantity) as cumq
     from t left outer join
          t tprev
          on t.item = tprev.item and
             t.txnDate >= tprev.txnDate
     group by t.txnDate, t.Item, t.quantity
    )
 select tcum.item, tcum.txndate, MIN(tcumnext.txndate) as nextfilldate
 from tcum left outer join
      tcum tcumnext
      on tcum.item = tcumnext.item and
         tcum.date < tcumnext.date and
         tcumnext.cumq > 0 and
         tcum.cumq = 0
group by tcum.item, tcum.txndate