簡體   English   中英

SQL MIN日期時間基於另一個列中值的首次出現

[英]SQL MIN Datetime based on first occuranceof a value in another column

這就是我所擁有的

ID  Name    DateTime    Value   Group

1   Mark    1/1/2010     0        1
2   Mark    1/2/2010     1        1
3   Mark    1/3/2010     0        1
4   Mark    1/4/2010     0        2
40  Mark    1/5/2010     1        2
5   Mark    1/9/2010     1        2
6   Mark    1/6/2010     1        2
7   Kelly   1/1/2010     0        3
8   Kelly   1/2/2010     1        3
9   Kelly   1/3/2010     1        3
10  Nancy   1/4/2010     0        4
11  Nancy   1/5/2010     0        4
12  Nancy   1/6/2010     1        5 
13  Nancy   1/7/2010     0        5

我想要的是在值變為1之后,以最少的日期時間獲取每個“組”的每個“名稱”的行。從上面的示例中,我需要獲取

3   Mark    1/3/2010     0        1
6   Mark    1/6/2010     1        2
9   Kelly   1/3/2010     1        3
13  Nancy   1/7/2010     0        5

根據您對規則的描述,我認為輸出實際上會有所不同,因為2010年1月5日是第一個DateTime,其中Mark的第2組的值= 1。

ID  Name    DateTime    Value   Group
3   Mark    2010-01-03  0       1
6   Mark    2010-01-06  1       2
9   Kelly   2010-01-03  1       3
13  Nancy   2010-01-07  0       5

下面的代碼將按此SQLFiddle中的說明工作。

SELECT sub.ID
    , sub.Name
    , sub.[DateTime]
    , sub.Value
    , sub.[Group]
FROM 
    (SELECT t.ID
        , t.Name
        , t.[DateTime]
        , t.Value
        , t.[Group]
        , SequentialOrder = ROW_NUMBER() OVER
            (PARTITION BY t.Name, t.[Group]
            ORDER BY t.[DateTime])
    FROM Test t
    JOIN 
        (SELECT Name
            , [Group]
            , MinimumDateTime = MIN([DateTime])
        FROM Test
        WHERE Value = 1
        GROUP BY Name
            , [Group]) mint
        ON t.Name = mint.Name
        AND t.[Group] = mint.[Group]
    WHERE t.[DateTime] > mint.MinimumDateTime) sub
WHERE sub.SequentialOrder = 1
ORDER BY ID;

以下是我的查詢,它假設接收記錄是按其日期順序進行的

WITH TBL_1 AS
(
SELECT A.*, ROW_NUMBER() OVER(PARTITION BY NAME, GROUP ORDER BY DATE) AS RN
FROM TABLE
WHERE (NAME, GROUP) IN
(SELECT NAME, GROUP FROM TABLE WHERE VALUE = 1)
),
TBL_2 AS
(
SELECT * FROM TBL_1 WHERE VALUE = 1
),
TBL_3 AS
(
SELECT A.*
FROM TBL_1 AS A
INNER JOIN TBL_2 AS B
ON  B.NAME = A.NAME
AND B.GROUP = A.GROUP
AND A.RN > B.RN
)

SELECT *
FROM TBL_3
WHERE (NAME, GROUP, DATE) IN
(SELECT NAME, GROUP, MIN(DATE) FROM TBL_3 GROUP BY NAME, GROUP)

在SQL Server 2012中,您可以執行以下操作:

SELECT * FROM (
  SELECT DISTINCT
    ID,
    Name,
    DateTime,
    Value,
    Gr,
    LAG(ID) OVER (PARTITION BY Name, Gr ORDER BY DateTime) F
  FROM (
    SELECT
      ID,
      Name,
      DateTime,
      Value,
      Gr,
      CASE WHEN LAG(Value) OVER (PARTITION BY Name, Gr ORDER BY DateTime) = 1 THEN 1 ELSE 0 END F
    FROM
      T
  ) TT

  WHERE F = 1

) TT WHERE F IS NULL

ORDER BY Gr, Name, DateTime

小提琴: http ://www.sqlfiddle.com/#!6 / 5a0fa2 /19

使用窗口功能:

with cte as (
    select
        *,
        row_number() over(partition by [Group], Name order by [DateTime]) as rn,
        dense_rank() over(order by [Group], Name) as rnk
    from Table1
)
select c1.*
from cte as c1
     inner join cte as c2 on c2.rn = c1.rn - 1 and c2.rnk = c1.rnk and c2.Value = 1
where
    not exists (select * from cte as c3 where c3.rn <= c1.rn - 2 and c3.rnk = c1.rnk and c3.Value = 1)

或申請:

select t1.*
from Table1 as t1
    cross apply (
        select top 1 t2.Value, t2.DateTime
        from Table1 as t2
        where
            t2.[Group] = t1.[Group] and t2.Name = t1.Name and
            t2.[DateTime] < t1.[DateTime]
        order by t2.[Datetime] desc
    ) as t2
where
    t2.Value = 1 and
    not exists (
        select *
        from Table1 as t3
        where
            t3.[Group] = t1.[Group] and t3.Name = t1.Name and
            t3.[DateTime] < t2.[DateTime] and t3.Value = 1
    )

sql小提琴演示

更新忘了提到您的輸出似乎不正確-第二行應該是id = 6而不是5(請參閱sql小提琴)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM