sql server找出第一次出现和最后一次出现并替换它们

时间:2014-06-19 00:27:13

标签: sql-server tsql sql-server-2012

我已经编写了一个查询来获取特定日期范围的员工符号..这给出了像这样的结果

Name     Type    Date         Code
----     ----    --------      ---
Mark     Dev    25/02/2014      a
Mark     Dev    26/02/2014      b
Mark     Dev    27/02/2014      c
Mark     Dev    28/02/2014      a
Mark     Dev    29/02/2014      b
Mark     Dev    30/02/2014      c
Rob      Dev    25/02/2014      c
Rob      Dev    26/02/2014      a
Rob      Dev    27/02/2014      b
Rob      Dev    28/02/2014      b
Rob      Dev    29/02/2014      c
Rob      Dev    30/02/2014      a
Pete     Dev    25/02/2014      a
Pete     Dev    26/02/2014      a
Pete     Dev    27/02/2014      a
Pete     Dev    28/02/2014      a
Pete     Dev    29/02/2014      b
Pete     Dev    30/02/2014      c

我想替换第一次出现的' [代码]和最后一次出现的' b'与每个员工一起使用' x'

我的查询看起来像这样..

Select  e.Name
       ,e.Type
       ,l.Date
       ,lc.Code
  From
         Employee  e
                      Inner Join leave l on e.empid = l.empid
                      Inner Join leaveCode lc on lc.lcodeid = l.lcodeid
  order by e.identfier,l.date

那么,我怎样才能通过替换' b' ...的第一次和最后一次来选择所有数据。

我试过..

Select 
       data.Name,
       data.Type,
       data.Date,
       (CASE WHEN ((Select TOP 1 data.Date from data where data.code = 'b') = data.Date) THEN 'x'  END) AS Code
From
(Select  e.Name
       ,e.Type
       ,l.Date
       ,lc.Code
  From
         Employee  e
                      Inner Join leave l on e.empid = l.empid
                      Inner Join leaveCode lc on lc.lcodeid = l.lcodeid
  order by e.identfier,l.date) as data

1 个答案:

答案 0 :(得分:1)

我会在每行添加一个row_number(),按名称分区,按日期排序。

这为Mark提供了每一行,例如,1-6的数字。

然后,您按名称min/max查询where type='x' ID,并将其与原始数据相关联。

    declare @data table (Name nvarchar(100), Type nvarchar(10), Date date, Code nvarchar(1))

    insert into @data
    select 'Mark',     'Dev',    '2014-04-25',      'a' union all
    select 'Mark',     'Dev',    '2014-04-26',      'b' union all
    select 'Mark',     'Dev',    '2014-04-27',      'c' union all
    select 'Mark',     'Dev',    '2014-04-28',      'a' union all
    select 'Mark',     'Dev',    '2014-04-29',      'b' union all
    select 'Mark',     'Dev',    '2014-04-30',      'c' union all
    select 'Rob',      'Dev',    '2014-04-25',      'c' union all
    select 'Rob',      'Dev',    '2014-04-26',      'a' union all
    select 'Rob',      'Dev',    '2014-04-27',      'b' union all
    select 'Rob',      'Dev',    '2014-04-28',      'b' union all
    select 'Rob',      'Dev',    '2014-04-29',      'c' union all
    select 'Rob',      'Dev',    '2014-04-30',      'a' union all
    select 'Pete',     'Dev',    '2014-04-25',      'a' union all
    select 'Pete',     'Dev',    '2014-04-26',      'a' union all
    select 'Pete',     'Dev',    '2014-04-27',      'a' union all
    select 'Pete',     'Dev',    '2014-04-28',      'a' union all
    select 'Pete',     'Dev',    '2014-04-29',      'b' union all
    select 'Pete',     'Dev',    '2014-04-30',      'c'

    ;with rowid as (
         select row_number() over(partition by name order by name, date) as id,
         *
         from @data)

    select t1.*
case when t1.id=filter.minid then 'first x' else null end as [firstreplace],
       case when t1.id=filter.maxid then 'last x' else null end as [lastreplace]
    from rowid t1
    join (select min(id) as minid, max(id) as maxid, name from rowid where code='b' group by name) as filter
       on t1.name=filter.name
       and (t1.id=filter.minid or t1.id=filter.maxid)

Fiddle here.

如果你想要分钟,只需取出and (t1.id=filter.minid *or t1.id=filter.maxid*)行的最大值,反之亦然。