English 中文(简体)
服务器数据转换
原标题:SQL Server Data Conversion

我有以下格式的数据:

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

Edit: 更新数据。

我如何能够轻易转换数据?

这是一次转换。

感谢评论/回答!

最佳回答

下文将产生预期产出,但我不敢肯定,如果你不做更好的勾销,这就是C#Q。

Update This has been updated to a proper gaps and island solution. This is based on the MSDN article Islands and Gaps in Sequential Numbers by Alexander Kozak. This could be improved on by using CTE s and also the Exists could be replaced with LEFT JOINs.

应当指出,这取决于日期是否没有任何时间组成部分。 如果有时间组成部分,就必须先撤除。

产出

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

声明

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
问题回答

采用康拉德测试数据和Izik Ben Gans方法!

;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




相关问题
How to write this T-SQL WHERE condition?

I ve got two tables: TableA Col1 Col2 TableB Col3 Col4 I want to join them together: SELECT * from TableA join TableB ON (...) Now, in place of ... I need to write an expression ...

Customer and Order Sql Statement

TSQL query to select all records from Customer that has an Order and also select all records from customer that does not have an Order. The table Customer contains a primary key of CustomerID. The ...

Recommended way of querying multiple Versioned tables

Have a win 2003 box with MSSQL 2005 running on it. There is a database which is populated every morning with new/modified SalesOrder made the previous day. The database has several tables: SalesOrder, ...

update duplicate record

I have a table with the following fields Id Name IsPublic i need to write a sql query that updates IsPublic to false where name has a duplicate. Only one of the duplicates should have IsPublic = ...

Define variable to use with IN operator (T-SQL)

I have a Transact-SQL query that uses the IN operator. Something like this: select * from myTable where myColumn in (1,2,3,4) Is there a way to define a variable to hold the entire list "(1,2,3,4)"? ...

Selecting records during recursive stored procedure

I ve got a content management system that contains a hierarchical structure of categories, with sub-categories subject to different ordering options at each level. Currently, that s retrieved by a (...

热门标签