2011-01-07 66 views
1

我在格式数据:SQL Server数据转换

Date, FirstName, LastName, Unit 
Jan1 , Bob  , Guy  , Home 
Jan2 , Bob  , Guy  , Home 
Jan3 , Bob  , Guy  , Home 
Jan5 , Bob  , Guy  , Home 
Jan6 , Bob  , Guy  , Home 
Jan7 , Bob  , Guy  , Home 
Jan8 , Bob  , Guy  , Offsite 
Jan3 , Jane  , Doe  , Home 
Jan4 , Jane  , Doe  , Home 
Jan5 , Jane  , Doe  , Home 
Jan9 , Bob  , Guy  , Home 
Jan10, Bob  , Guy  , Home 
Jan11, Bob  , Guy  , Home 
Jan12, Jane  , Doe  , Home 
Jan13, Jane  , Doe  , Home 
Jan14, Jane  , Doe  , Home 

,我希望它在格式

DateStart, DateEnd, FirstName, LastName, Unit 
Jan1  , Jan3 , Bob  , Guy  , Home 
Jan5  , Jan7 , Bob  , Guy  , Home 
Jan8  , Jan8 , Bob  , Guy  , Offsite 
Jan3  , Jan5 , Jane  , Doe  , Home 
Jan9  , Jan11 , Bob  , Guy  , Home 
Jan12 , Jan14 , Jane  , Doe  , Home 

编辑:更新的数据。

如何轻松转换数据?

这是一次性转换。

感谢您的意见/答案!

+4

不完全清楚你想要做什么;例如Jane Doe为什么是“DateEnd”= Jan3,而Bob Guy则为空?给定的名字/姓氏可以有多于两个条目?如果是:您是否想要为该名称使用DateStart = MIN(Date)和DateEnd = MAX(Date)? – 2011-01-07 21:42:50

+0

同意marc_s ...我希望Jane Doe有一个无效的DateEnd,就像你的解释中的Bob一样?否则,你的意思是最后一行只有没有DateEnd? – Matthew 2011-01-07 22:11:25

+0

@marc_s&@Mthethew PK Bob的DateEnd为空,因为他是单位中的最后一个人。给定的名字/姓氏可以有很多条目。在1月4日之后可能会有更多的“主页”条目,这会使第二张桌子上的Jan4条目的DateEnd为Jan4(如果它是不同的人),或者如果Bob有多个条目,则另一个日期为另一个人在他后面的家中有一个入口。每个单位的最新DateStart将有一个空DateEnd – 2011-01-07 22:30:55

回答

4

的SQL下面将产生所需的输出,但我不知道,如果你不更好写,这是C#

更新 这已更新到适当的时间间隔和岛屿的解决方案。这是基于Alexander Kozak的MSDN文章Islands and Gaps in Sequential Numbers。这可以通过使用CTE来改进,也可以用LEFT JOIN替换Exists。

应该指出,这依赖于日期没有任何时间组件。如果有时间组件,它将不得不被删除。

输出

Date     enddate     FirstName LastName Unit 
----------------------- ----------------------- --------- -------- ------- 
2011-01-01 00:00:00.000 2011-01-03 00:00:00.000 Bob  Guy  Home 
2011-01-03 00:00:00.000 2011-01-05 00:00:00.000 Jane  Doe  Home 
2011-01-05 00:00:00.000 2011-01-07 00:00:00.000 Bob  Guy  Home 
2011-01-08 00:00:00.000 2011-01-08 00:00:00.000 Bob  Guy  Offsite 
2011-01-09 00:00:00.000 2011-01-11 00:00:00.000 Bob  Guy  Home 
2011-01-12 00:00:00.000 2011-01-14 00:00:00.000 Jane  Doe  Home 

SQL语句

SET NOCOUNT On 

DECLARE @Test 
Table (
    Date datetime, 
    FirstName varchar(100), 
    LastName varchar(100), 
    Unit varchar(7)) 



INSERT INTO @Test VALUES ('01/01/2011' , 'Bob', 'Guy', 'Home') 
INSERT INTO @Test VALUES ('01/02/2011' , 'Bob', 'Guy', 'Home') 
INSERT INTO @Test VALUES ('01/03/2011' , 'Bob', 'Guy', 'Home') 
INSERT INTO @Test VALUES ('01/05/2011' , 'Bob', 'Guy', 'Home') 
INSERT INTO @Test VALUES ('01/06/2011' , 'Bob', 'Guy', 'Home') 
INSERT INTO @Test VALUES ('01/07/2011' , 'Bob', 'Guy', 'Home') 
INSERT INTO @Test VALUES ('01/08/2011' , 'Bob', 'Guy', 'Offsite') 
INSERT INTO @Test VALUES ('01/03/2011' , 'Jane', 'Doe', 'Home') 
INSERT INTO @Test VALUES ('01/04/2011' , 'Jane', 'Doe', 'Home') 
INSERT INTO @Test VALUES ('01/05/2011' , 'Jane', 'Doe', 'Home') 
INSERT INTO @Test VALUES ('01/09/2011' , 'Bob', 'Guy', 'Home') 
INSERT INTO @Test VALUES ('01/10/2011' , 'Bob', 'Guy', 'Home') 
INSERT INTO @Test VALUES ('01/11/2011' , 'Bob', 'Guy', 'Home') 
INSERT INTO @Test VALUES ('01/12/2011' , 'Jane', 'Doe', 'Home') 
INSERT INTO @Test VALUES ('01/13/2011' , 'Jane', 'Doe', 'Home') 
INSERT INTO @Test VALUES ('01/14/2011' , 'Jane', 'Doe', 'Home') 


SELECT 
    t1.Date, 
    MIN(t2.Date) enddate, 
    t1.FirstName, 
    t1.LastName, 
    t1.Unit 
FROM 

    (SELECT * 
    FROM 
     @Test t1 
    WHERE 
     NOT EXISTS(SELECT * FROM @Test t2 
        WHERE 
         t1.firstName = t2.FirstName 
         AND t1.LastName = t2.LastName 
         AND t1.Unit = t2.Unit 
         and t1.Date - t2.Date = 1)) 
     t1 


     INNER JOIN (SELECT * FROM @Test t1 

    WHERE 
     NOT EXISTS(SELECT * FROM @Test t2 
        WHERE 
         t1.firstName = t2.FirstName 
         AND t1.LastName = t2.LastName 
         AND t1.Unit = t2.Unit 
         and t2.Date - t1.Date = 1)) t2 
     ON 
     t1.firstName = t2.FirstName 
         AND t1.LastName = t2.LastName 
         AND t1.Unit = t2.Unit 
         AND t1.Date <= t2.Date 
     GROUP BY 
     t1.Date, 
     t1.FirstName, 
     t1.LastName, 
     t1.Unit 
4

使用康拉德的测试数据和伊茨克奔甘的做法!

;WITH base AS ( 
SELECT FirstName, 
      LastName, 
      Unit, 
      Date, 
      DATEDIFF(DAY,0,Date) - 
         DENSE_RANK() OVER (PARTITION BY FirstName, LastName, Unit 
              ORDER BY DATEDIFF(DAY,0,Date)) AS G 
FROM  @Test 
) 
SELECT FirstName, LastName, Unit, MIN(Date) DateStart,MAX(Date) DateEnd 
FROM base 
GROUP BY G, FirstName, LastName, Unit 
相关问题