【问题标题】:SQL Query to Calculate the Rolling Difference by Date按日期计算滚动差异的 SQL 查询
【发布时间】:2014-11-18 07:18:49
【问题描述】:

我似乎无法将这个工作完全满足需要。

我正在使用 MS SQL Management Studio 2008。

我有一张桌子(实际上是几张),但请保持简单。该表包含每个项目 (SKU) 的每日库存数据。

SKU DataDate               Web_qty
2   2014-11-17 00:00:00    404
2   2014-11-18 00:00:00    373
2   2014-11-19 00:00:00    1350
66  2014-11-17 00:00:00    3624
66  2014-11-18 00:00:00    3576
66  2014-11-19 00:00:00    3570
67  2014-11-17 00:00:00    9353
67  2014-11-18 00:00:00    9297
67  2014-11-19 00:00:00    9250

我只需要选择查询来返回这个:

SKU DataDate               Difference
2   2014-11-17 00:00:00    ---
2   2014-11-18 00:00:00    -31
2   2014-11-19 00:00:00    +977
66  2014-11-17 00:00:00    ---
66  2014-11-18 00:00:00    -48
66  2014-11-19 00:00:00    -6
67  2014-11-17 00:00:00    ---
67  2014-11-18 00:00:00    -56
67  2014-11-19 00:00:00    -47

我不需要 --- 部分,我只是展示了这一点,以提醒人们注意这个事实,因为它是第一个记录,所以无法计算。

我尝试过使用派生表,但它变得有点混乱,我需要使用一个工作示例以便更好地理解它。

如果有人能指出我正确的方向,我相信我可以将其他表格重新组合在一起(即 SKU 描述和价格)。

真的很感谢大家的时间

凯夫

【问题讨论】:

  • 对于每个SKUDatadate 是否总是连续的?
  • 是的,一旦将 SKU 添加到 SKU 表中,那么即使在此期间该值没有变化,每天也会将一个库存数字添加到库存表中。实际上,我也为定价表这样做。我需要更改它,因为表变得非常大,但更改很少。我需要在一个日期范围内创建价格:)
  • @Jaugar Chang,我明白你现在的意思了!如果您在特定日期有多个 Web_Qty(例如 2014 年 11 月 18 日的两次数量更新),则查询将出错,因为它将返回两个值,并且不知道从 2014 年 11 月 19 日值中减去哪个值。我会在下面的答案中记下以通知其他人。
  • 如果一天有多个Web_Qty,你可以在计算差值之前将Web_Qty相加。我担心Datadate 是否不连续,例如11-1711-1911-18 没有记录)。 11-19 有什么区别? 11-19 的 Web_Qty 或 11-1911-17 之间的 Web_Qty 差异?
  • 是的,当然这是此解决方案的另一种可能性...不过我的问题已解决,我没有任何这些问题,将您的查询更改为更新查询并在我的表中添加了一列.现在我在存储我的每日库存数据时即时计算这个,所以实际上不需要再次执行查询。感谢您的帮助,您非常乐于助人,我们对此表示赞赏。

标签: sql-server date


【解决方案1】:

试试这个。使用correlated sub-query 查找rolling difference

CREATE TABLE #tem
  (SKU      INT,DataDate DATETIME,Web_qty  INT)

INSERT #tem
VALUES( 2,'2014-11-17 00:00:00',404),
       (2,'2014-11-18 00:00:00',373),
       (2,'2014-11-19 00:00:00',1350),
       (66,'2014-11-17 00:00:00',3624),
       (66,'2014-11-18 00:00:00',3576),
       (66,'2014-11-19 00:00:00',3570),
       (67,'2014-11-17 00:00:00',9353),
       (67,'2014-11-18 00:00:00',9297),
       (67,'2014-11-19 00:00:00',9250)

SELECT *,
       Web_qty - (SELECT Web_qty
                  FROM   #tem a
                  WHERE  a.sku = b.SKU
                         AND a.DataDate = Dateadd(dd, -1, b.DataDate)) Roll_diff
FROM   #tem b 

【讨论】:

  • 完美的例子,谢谢,我的问题解决了。
  • 注意:这是一个很好的例子,可以满足我的需要。但是,它的限制是每个日期只能有“一个”Web_Qty。否则会抛出错误,因为子查询返回多个值。
  • @Kev 在这种情况下,您的预期输出是什么。
  • 嗨,实际上对我来说我“不应该”有这种情况。虽然由于测试,我损坏了我的数据:(。如果我确实有这个,但我可能会使用 Min(在我的情况下)只带回一个数字而不是错误?
【解决方案2】:

我知道这是一个旧线程,但我碰巧遇到了类似的问题,最后我用 Window 函数解决了它。它适用于 SQL 2014,但不确定 2008。

它还解决了潜在的非连续数据以及没有变化的行的问题。希望它可以帮助那里的人!

CREATE TABLE #tem
(SKU INT,DataDate DATETIME,Web_qty INT)

INSERT #tem
VALUES( 2,'2014-11-17 00:00:00',404),
   (2,'2014-11-18 00:00:00',373),
   (2,'2014-11-19 00:00:00',1350),
   (2,'2014-11-20 00:00:00',1350),
   (2,'2014-11-21 00:00:00',1350),
   (66,'2014-11-17 00:00:00',3624),
   (66,'2014-11-18 00:00:00',3576),
   (66,'2014-11-19 00:00:00',3570),
   (66,'2014-11-20 00:00:00',3590),
   (66,'2014-11-21 00:00:00',3578),
   (67,'2014-11-17 00:00:00',9353),
   (67,'2014-11-18 00:00:00',9297),
   (67,'2014-11-19 00:00:00',9250),
   (67,'2014-11-20 00:00:00',9250),
   (67,'2014-11-21 00:00:00',9240)

;WITH A AS (
SELECT 
  SKU,
  DataDate,
  Web_Qty,
  Web_qty - LAG(Web_qty,1, 0)
    OVER (PARTITION BY SKU ORDER BY DataDate) Roll_diff
FROM #tem b 
)
SELECT
  SKU,
  DataDate ValidFromDate,
  Lead(DataDate, 1, DateFromParts(9999,12,31))  OVER (PARTITION BY SKU ORDER BY DataDate) ValidToDate,
  Web_Qty
FROM A WHERE Roll_diff <> 0

【讨论】:

  • 在我看来,比另一个更好的解决方案,正是我想要的,谢谢。
猜你喜欢
  • 2022-01-20
  • 1970-01-01
  • 1970-01-01
  • 2013-10-14
  • 1970-01-01
  • 1970-01-01
  • 2022-08-15
  • 2011-11-29
  • 2012-12-22
相关资源
最近更新 更多