2011-01-07 69 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 
相關問題