SQL Server数据转换
-
08-10-2019 - |
题
我有格式的数据:
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
编辑:更新数据。
如何轻松转换数据?
这是一次转换。
感谢您的评论/答案!
解决方案
下面的SQL会产生所需的输出,但是我不确定您是否不太好编写这是C#
更新这已更新为适当的差距和岛屿解决方案。这是基于MSDN文章 顺序数字的岛屿和差距 亚历山大·科扎克(Alexander Kozak)。可以通过使用CTE来改善这一点,并且可以用左连接来代替存在。
应该注意的是,这取决于日期没有任何时间组件。如果有时间组件,则必须在前面删除。
输出
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
其他提示
使用Conrad的测试数据和Itzik Ben Gan的方法!
;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
不隶属于 StackOverflow