在同一数据列中检测具有日期差异的样本

时间:2018-11-09 14:33:10

标签: sql-server tsql

表格:

如何扫描每个SampleRef并标记一个交货日期相距6个月以上的交货。因此,从上面的示例中,只有SampleRef A的日期相隔6个月,例如使用T-SQL的示例01/04/2013和16/02/2014。

结果:

谢谢!

4 个答案:

答案 0 :(得分:1)

--Is there a record belonging to a SampleRef, where for any row, there is an absence of any 
--delivery within six months prior, however there is some prior delivery
SELECT 
     DISTINCT T1.SampleRef FROM YourTable T1
                WHERE EXISTS(
                            SELECT 0 FROM YourTable T2 
                                    WHERE 
                                        T1.SampleRef = T2.SampleRef And 
                                        Not EXISTS( -- was there no delivery in last 6 months
                                            SELECT 0 FROM YourTable T3
                                                WHERE T3.SampleRef = T2.SampleRef
                                                AND 
                                                T3.DeliverYdate >= DATEADD(mm,-6,T2.DeliveryDate)
                                                AND 
                                                T3.DeliveryDate < T2.DeliveryDate 
                                                )
                                        And Exists --check that there was howevwer a prior delivery
                                        (
                                        SELECT 0 FROM YourTable T4
                                                WHERE T4.SampleRef = T2.SampleRef
                                                AND 
                                                T4.DeliverYdate < T2.DeliveryDate 
                                        )                                                                               
                            )

答案 1 :(得分:1)

您可以使用ROW_NUMBER()对SampleRef中的样本进行排序,然后将该排序后的集合与其自身连接,并找到下一个可用样本超过6个月后的任何记录。 (请注意,下面的示例代码不会告诉您距集合中的最后一个样本是否已经超过6个月了-您可以根据需要修改查询以进行此操作)

您没有为表格指定名称,因此将下面查询中的YourTableNameHere替换为表格名称。

WITH SamplesNumberedByGroup AS (
    SELECT
        SampleRef,
        DeliveryDate,
        ROW_NUMBER() OVER (PARTITION BY SampleRef ORDER BY DeliveryDate) AS 'SampleNum' 
    FROM
        YourTableNameHere
)

SELECT
    DISTINCT
    S.SampleRef
FROM
    SamplesNumberedByGroup S
    INNER JOIN SamplesNumberedByGroup S2 ON S.SampleRef = S2.SampleRef AND S2.SampleNum = S.SampleNum + 1
WHERE
    S2.DeliveryDate > DATEADD(MONTH,6,S.DeliveryDate);

如果要查看每个样本中距离下一个可用样本超过6个月的时间(而不仅仅是查看哪个sampleref的间隔至少为6个月),请改用以下代码。

WITH SamplesNumberedByGroup AS (
    SELECT
        SampleRef,
        DeliveryDate,
        ROW_NUMBER() OVER (PARTITION BY SampleRef ORDER BY DeliveryDate) AS 'SampleNum' 
    FROM
        YourTableNameHere
)

SELECT
    S.SampleRef
    ,S.Price
    ,S.DeliveryDate
FROM
    SamplesNumberedByGroup S
    INNER JOIN SamplesNumberedByGroup S2 ON S.SampleRef = S2.SampleRef AND S2.SampleNum = S.SampleNum + 1
WHERE
    S2.DeliveryDate > DATEADD(MONTH,6,S.DeliveryDate);

如果您需要包含超过6个月的所有条目,但也没有“下一个”条目,则将INNER JOIN替换为LEFT OUTER JOIN并在其中添加OR (S2.DeliveryDate IS NULL AND GETDATE() > DATEADD(MONTH,6,S.DeliveryDate) where语句。

答案 2 :(得分:1)

为您提供其他选项:

每个SampleRef的MIN和MAX,以及大于6个月的差异。

或使用LAG()并获取每条记录的先前交货日期,然后查看哪个记录的先前交货时间超过六个月。

DECLARE @TestData TABLE
    (
        [SampleRef] CHAR(1)
      , [DeliveryDate] DATE
    );

INSERT INTO @TestData (
                          [SampleRef]
                        , [DeliveryDate]
                      )
VALUES ( 'A', '4/1/2013' )
     , ( 'A', '2/3/2013' )
     , ( 'A', '2/16/2014' )
     , ( 'A', '6/12/2015' )
     , ( 'A', '6/26/2015' )
     , ( 'A', '6/26/2015' )
     , ( 'A', '2/10/2015' )
     , ( 'B', '6/26/2015' )
     , ( 'B', '6/27/2015' )
     , ( 'B', '6/28/2015' )
     , ( 'B', '6/29/2015' )
     , ( 'B', '6/30/2015' )
     , ( 'B', '7/1/2015' );


--This looks at all dates per sampleref, min and max and filters those greater than 6 months
SELECT *
FROM   (
           SELECT   [SampleRef]
                  , MIN([DeliveryDate]) AS [MinDeliveryDate]
                  , MAX([DeliveryDate]) AS [MaxDeliveryDate]
           FROM     @TestData
           GROUP BY [SampleRef]
       ) AS [SampleRef]
WHERE  DATEDIFF(
                   MONTH
                 , [SampleRef].[MinDeliveryDate]
                 , [SampleRef].[MaxDeliveryDate]
               ) > 6;


--This will get the prior delivery date for each record and then you can see all where there was a span greater than six months.
SELECT *
     , DATEDIFF(
                   MONTH
                 , [SampleRef].[PreviousDelivery]
                 , [SampleRef].[DeliveryDate]
               ) AS [MonthSincePreviousDelivery]
FROM   (
           SELECT *
                , LAG([DeliveryDate], 1, [DeliveryDate]) OVER ( PARTITION BY [SampleRef]
                                                                ORDER BY [DeliveryDate]
                                                              ) AS [PreviousDelivery]
           FROM   @TestData
       ) AS [SampleRef]
WHERE  DATEDIFF(
                   MONTH
                 , [SampleRef].[PreviousDelivery]
                 , [SampleRef].[DeliveryDate]
               ) > 6;

答案 3 :(得分:0)

使用EXISTS()检查是否存在任何行,其中同一SampleRef的下一个较高行的DATEDIFF超过6个月。

相关问题