【问题标题】:Date difference for same ID同一ID的日期差异
【发布时间】:2019-04-30 17:01:12
【问题描述】:

我有一个类似的数据集

    +----+------------+------------+------------+

    | ID |   Udate    | last_code  | Ddate      | 
    +----+------------+------------+------------+
    |  1 | 05/11/2018 | ACCEPTED   | 13/10/2018 |
    |  1 | 03/11/2018 | ATTEMPT    | 13/10/2018 | 
    |  1 | 01/11/2018 | INFO       | 13/10/2018 |
    |  1 | 22/10/2018 | ARRIVED    | 13/10/2018 | 
    |  1 | 15/10/2018 |   SENT     | 13/10/2018 | 
    +----+------------+------------+------------+

我正在尝试获取 Udate 上每个代码的日期差异,但对于第一个日期,我想在 Udate 和 Ddate 之间进行日期差异。

所以我一直在尝试:

DATEDIFF(DAY,LAG(Udate) OVER (PARTITION BY Shipment_Number ORDER BY Udate), Udate)

要获取日期之间的差异并且到目前为止它有效,但我还需要 Udate 和 Ddate 之间的第一个日期差异。

我在想ISNULL()

另外,最后我还需要代码之间的平均天数,通常它们保持相同的模式。样本输出数据:

    +----+------------+------------+------------+------------+

    | ID |   Udate    | last_code  | Ddate      | Difference |
    +----+------------+------------+------------+------------+
    |  1 | 05/11/2018 | ACCEPTED   | 13/10/2018 |     2      |
    |  1 | 03/11/2018 | ATTEMPT    | 13/10/2018 |     2      |
    |  1 | 01/11/2018 | INFO       | 13/10/2018 |     10     |
    |  1 | 22/10/2018 | ARRIVED    | 13/10/2018 |     7      |
    |  1 | 15/10/2018 |   SENT     | 13/10/2018 |     2      |
    +----+------------+------------+------------+------------+

请注意,当没有之前的代码时,日期差异在 Udate 和 Ddate 之间。

任何想法都将不胜感激。

谢谢。

【问题讨论】:

  • 你能提供样本输出数据吗?
  • 是的,对不起。现已编辑
  • 你能澄清一下“另外,最后我需要平均代码之间的天数” 是什么意思吗?是否有一些额外的部分需要解决。我打算为您提供的结果提供一个答案,但老实说,它只是将您已经表达的想法形式化 - 使用 `IsNull(LAG(Udate) OVER (PARTITION BY Shipment_Number ORDER BY Udate), Ddate)!
  • “我在想ISNULL()”——这个想法很好,你试过了吗?

标签: sql-server tsql average lag datediff


【解决方案1】:

嗯,ISNULL 是去这里的方式。
既然你也想要平均差,你可以用一个普通的表表达式来得到差,然后查询得到平均值:

首先,创建并填充示例数据(在您以后的问题中保存我们这一步)

-- This would not be needed if you've used ISO8601 for date strings (yyyy-mm-dd | yyyymmdd)
SET DATEFORMAT DMY; 

DECLARE @T AS TABLE
    (
    ID int,
    UDate date,
    last_code varchar(10),
    Ddate date
    ) ;

INSERT INTO @T (ID, Udate, last_code, Ddate) VALUES

(1, '05/11/2018', 'ACCEPTED', '13/10/2018'),
(1, '03/11/2018', 'ATTEMPT' , '13/10/2018'), 
(1, '01/11/2018', 'INFO'    , '13/10/2018'),
(1, '22/10/2018', 'ARRIVED' , '13/10/2018'), 
(1, '15/10/2018', 'SENT'    , '13/10/2018');

cte:

WITH CTE AS
(
    SELECT  ID, 
            Udate, 
            last_code, 
            Ddate,
            DATEDIFF(
                DAY, 
                ISNULL(
                    LAG(Udate) OVER(PARTITION BY ID ORDER BY Udate), 
                    Ddate
                ), 
                UDate
            ) As Difference
    FROM @T
)

查询:

SELECT *, AVG(Difference) OVER(PARTITION BY ID) As AverageDifference
FROM CTE;

结果:

ID  Udate       last_code   Ddate       Difference  AverageDifference
1   15.10.2018  SENT        13.10.2018  2           4
1   22.10.2018  ARRIVED     13.10.2018  7           4
1   01.11.2018  INFO        13.10.2018  10          4
1   03.11.2018  ATTEMPT     13.10.2018  2           4
1   05.11.2018  ACCEPTED    13.10.2018  2           4

【讨论】:

  • 哦,很好,看起来我与差异非常接近,但我对平均值有点困惑。 +
  • 如果我使用 AVG(Difference) OVER (PARTITION BY last_code),它不会给我所有 ID 的代码之间的平均差异吗?
  • 也许我误解了你想要的平均值。我以为你想要每个 ID 的平均值。您可以使用Partition by 子句,看看您使用不同的列会得到什么。
  • 是的,我问的方式有点令人困惑。干杯佐哈尔,不错的一个!!
  • 很高兴为您提供帮助 :-)
猜你喜欢
  • 1970-01-01
  • 2022-01-06
  • 1970-01-01
  • 2017-03-10
  • 1970-01-01
  • 1970-01-01
  • 2019-09-25
  • 2023-01-18
  • 2018-09-18
相关资源
最近更新 更多