1

这就是我所拥有的

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
4

4 回答 4

1

根据您对规则的描述,我相信输出实际上会有所不同,因为 2010-01-05 是第一个 DateTime,其中 Mark 的 Group 2 的 Value = 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;
于 2013-11-12T20:10:25.500 回答
0

下面是我的查询,它假设记录是按日期顺序接收的

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)
于 2013-11-12T19:53:21.157 回答
0

使用窗口函数:

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 fiddle demo

更新忘记提及您的输出似乎不正确 - 第二行应该有 id = 6 而不是 5(参见 sql fiddle)。

于 2013-11-12T20:52:09.033 回答
0

在 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

于 2013-11-12T20:18:50.353 回答