2014-09-25 230 views
0

如何计算日期间隔中两行之间的差异?

我想根据日期间隔比较来自Access 2010数据库的数据。示例我有来自各种采购订单的项目,我想维护这些项目交付到仓库的历史记录。因此,例如,我的采购订单要求提供数量为10的物料,并且可以部分以多次交货方式交付,并且我想知道此交货在日期间隔内是如何变化的。要填写日期字段,使用的标准如下所示:如果项目在QtyPending字段中有更新,我使用booelan字段复制当前行并将其停用,创建一个新条目,并更新QtyPending字段以更新当前日期活动记录是项目的实际状态。所以我有一个包含有关这些项目就像

 
    PO   POItem   QtyPending   Date   Active 
450000/09/2014  FALSE 
450000/09/2014  TRUE 
4500000122  30    5    03/09/2014  FALSE 
4500000122  30    1    04/09/2014  TRUE 

有了这个例子中的信息表,对于第一个项目,就意味着,从日期01/09至04/09的QtyPending场没有遭受一个变种,这意味着供应商没有交付给我,但从01/09到05/08,他给了我一个2的材料的数量。第二个,从2009年3月3日到2009年4月,供应商向我交付了4件材料。所以,如果我要使得从2014年2月9日的报告查询2014年4月9日,预期输出是这样的:

 
    PO   POItem   QtyDelivered 
450000
4500000122  30     4 

而从31/08 /报告2014年2014年10月9日,将有这样的输出

 
    PO   POItem   QtyDelivered 
450000
4500000122  30     4 

我不跟查询上来,使这个报告。谁能帮我?

+0

灿日期跨度参加两个以上的记录? “Active”字段有什么作用? (更多的问题可以参考...这不是很清楚!) – Smandoli 2014-09-25 20:15:07

+0

您的要求听起来非常类似于以前的问题[这里](http://stackoverflow.com/q/26046828/2144390)。看看答案,看看他们中的一个能否帮助你。 ([我的答案](http://stackoverflow.com/a/21033184/2144390)显示了如何使用* self-join *来避免记录集循环。) – 2014-09-25 20:20:57

+0

Smandoli,活动字段,如果FALSE,它告诉记录仅存储用于历史目的以查询项目的过去状态。而且,如果active为TRUE,意味着项目的当前状态,所以如果我想查询项目的实际状态,我需要做的唯一事情就是WHERE Active = TRUE – 2014-09-26 11:55:17

回答

0

我想出了这个查询解决了这个问题,它不是那么简单

SELECT 
ItmDtIni.PO 
,ItmDtIni.POItem AS [PO Item] 
,ROUND(ItmDtIni.QtyPending - ItmDtEnd.QtyPending, 3) AS [Qty Delivered] 
,ROUND((ItmDtIni.QtyPending - ItmDtEnd.QtyPending) * ItmDtEnd.Price, 2) AS [Value delivered(US$)] 
//Filtering subqueries to bring only the items in the date interval to make a self join 
FROM (((SELECT 
     PO 
     ,POItem 
     ,QtyPending 
     ,MIN(Date) AS MinDate 
     FROM Item 
     WHERE Date BETWEEN FORMAT(begin_date, 'dd/mm/yyyy') AND FORMAT(end_date, 'dd/mm/yyyy') 
     GROUP BY 
     PO 
     ,POItem 
     ,QtyPending) AS ItmDtIni 
//Self join filtering to bring only items in the date interval with the previously filtered table 
INNER JOIN (SELECT 
      PO 
      ,POItem 
      ,QtyPending 
      ,Price 
      ,MAX(Date) AS MaxDate 
      FROM Item 
      WHERE Date BETWEEN FORMAT(begin_date, 'dd/mm/yyyy') AND FORMAT(end_date, 'dd/mm/yyyy') 
      GROUP BY 
      PO 
      ,POItem 
      ,QtyPending 
      ,Price) AS ItmDtEnd 
    ON ItmDtIni.PO = ItmDtEnd.PO 
    AND ItmDtIni.POItem = ItmDtEnd.POItem) 
INNER JOIN PO 
    ON ItmDtEnd.PO = PO.Numero) 
WHERE 
//Showing only items that had a variation in the date interval 
     ROUND(ItmDtIni.QtyPending - ItmDtEnd.QtyPending, 3) <> 0 
//Anchoring min date in the interval for each item found by the first subquery 
     AND ItmDtIni.MinDate = (SELECT MIN(Item.Date) 
           FROM Item 
           WHERE 
            ItmDtIni.PO = Item.PO 
           AND ItmDtIni.POItem = Item.POItem 
           AND Date BETWEEN FORMAT(begin_date, 'dd/mm/yyyy') AND FORMAT(end_date, 'dd/mm/yyyy')) 
//Anchoring max date in the interval for each item found by the second subquery 
    AND ItmDtEnd.MaxDate = (SELECT MAX(Item.Date) 
          FROM Item 
          WHERE 
           ItmDtEnd.PO = Item.PO 
          AND ItmDtEnd.POItem = Item.POItem 
          AND Date BETWEEN FORMAT(begin_date, 'dd/mm/yyyy') AND FORMAT(end_date, 'dd/mm/yyyy')) 
+0

一个更好的方法来做同样的事情,我张贴在另一个问题。在第一次尝试编写查询之后,我想到了一个更好的方法来完成它。那里是: http://stackoverflow.com/q/26465285/2726538 – 2014-11-07 18:47:33

0

有很多方法可以解决这个问题。最简单的方法是简单地查询两个日期之间的所有必要记录,循环查看并在结果中插入临时表。这个临时表可以成为您的报告的来源。很多人会因为没有使用大的查询而尖叫你,而是以最快和最简单的方式得到你想要的结果应该是你的首要任务。

您的模式问题是您没有为每条记录存储QtyDelivered。如果你愿意的话,为了得到需要的结果,总结它会是一件容易的事情。通过不存储此值,您已将简单而快速的查询转换为更难和更慢的查询,因为您需要以某种方式重新计算此值,并且必须在不忘记可能有两个以上记录。

要计算此值,可以使用子查询从前一行检索值,或者使用左连接进行相同操作。一旦你有这个值,你可以减去这两个来获得所需的差异;如果没有之前的行,则允许可能的Null值。一旦你有了这些值,你现在可以对它们进行求和以得到最终结果。请注意,为了执行这些计算,您需要有一个或两个以上的子查询级别。第一个查询应该是这样的:

Select PO, POItem, QtyPending, (Select Top 1 QtyPending from MyTable T2 where T1.PO = T2.PO and T2.Date < T1.Date And (T2.Date between @Date1 and @Date2) Order by T2.Date Desc) as QtyPending2 from MyTable T1 Where T1.Date between @Date1 and @Date2) ... 

以此为无论是另一个子查询或视图,然后你可以通过比较QtyPending和QtyPending2的值计算所需的差异;而不会忘记QtyPendin2可能为空。其余的步骤很容易做到。

请注意,上述示例适用于SQL Server,因此您可能必须对Access进行一些更改。无论如何,你可以在这里找到许多关于如何在Access下比较两行的例子。如前所述,您也可以使用左连接而不是子查询来比较行。

+0

我总结了要求。我正在使用SAP报告ME2N报告跟踪特定的采购订单交付。我正在导入它的Excel电子表格输出来处理和跟踪具有更高细节级别的项目。所以一件物品可能会在某个日期交付,并且由于某种类型的问题而遭受逆转。如果发生这种情况,QtyPending从0到10,例如,在日期间隔内给我一个-10的差异。所以,只是SUM()QtyPending我不会考虑这些负面差异,但对我来说知道给定的项目是否出现逆转是很重要的。 – 2014-09-26 12:05:49

相关问题