這是一個相當複雜的一系列步驟,但它是我解決了類似的問題的方法:
-- Sample Data
CREATE TABLE AdjacentValidity
(
RowID INT IDENTITY(1,1) NOT NULL,
Product VARCHAR(1) NOT NULL,
Start_Date DATETIME NOT NULL,
End_Date DATETIME NOT NULL
)
INSERT INTO AdjacentValidity (Product, Start_Date, End_Date)
SELECT 'A', '7/1/2013', '7/31/2013' UNION
SELECT 'A', '8/1/2013', '8/31/2013' UNION
SELECT 'A', '9/1/2013', '9/30/2013' UNION
SELECT 'B', '10/1/2013', '10/31/2013' UNION
SELECT 'B', '11/1/2013', '11/30/2013' UNION
SELECT 'A', '12/1/2013', '12/31/2013' UNION
SELECT 'A', '1/1/2014', '1/31/2014' UNION
SELECT 'A', '2/1/2014', '2/28/2014' UNION
SELECT 'A', '3/1/2014', '3/31/2014'
-- Modify the sample data to include necessary tags
CREATE TABLE #RawData
(
RawData_ID INT IDENTITY(1,1) NOT NULL,
Product VARCHAR(1) NOT NULL,
Start_Date DATETIME NOT NULL,
End_Date DATETIME NOT NULL,
isFirstOccurrence BIT NULL,
isLastOccurrence BIT NULL,
isFirstInstance BIT NULL,
isLastInstance BIT NULL
)
-- Load and flag first occurrences of a natural key
INSERT INTO #RawData
(
Product,
Start_Date,
End_Date,
isFirstInstance
)
SELECT
Product,
Start_Date,
End_Date,
CASE WHEN ROW_NUMBER() OVER
(
--PARTITION BY <NaturalKey>
ORDER BY Start_date
) = 1 THEN 1 ELSE 0 END AS isFirstOccurrence
FROM AdjacentValidity
-- update to flag the last sequential instance of a particalar data set, and the last occurrence of a natural key
UPDATE a
SET
a.isLastInstance =
CASE
WHEN
a.Product <> b.Product OR
DATEADD(m, 1, a.Start_Date) <> b.Start_Date OR
b.RawData_ID IS NULL
THEN 1
ELSE 0
END,
a.isLastOccurrence =
CASE
WHEN
b.RawData_ID IS NULL
THEN 1
ELSE 0
END
FROM
#RawData a
LEFT JOIN
#RawData b ON
b.RawData_ID = a.RawData_ID + 1 --AND
--b.<NaturalKey> = a.<NaturalKey>
-- flag first sequential instance of a particular data set
UPDATE b
SET
b.isFirstInstance =
CASE
WHEN
a.isLastInstance = 1
THEN 1
ELSE 0
END
FROM
#RawData a
LEFT JOIN
#RawData b ON
b.RawData_ID = a.RawData_ID + 1 --AND
--b.<NaturalKey> = a.<NaturalKey>
-- reduce the records to only those that are the first or last occurrence of a particular data set
CREATE TABLE #UniqueData
(
[UniqueData_ID] [int] IDENTITY(1,1) NOT NULL,
Start_Date DATETIME NOT NULL,
End_Date DATETIME NOT NULL,
Product VARCHAR(1) NULL,
isFirstOccurrence BIT NULL,
isLastOccurrence BIT NULL,
isFirstInstance BIT NULL,
isLastInstance BIT NULL
)
INSERT INTO #UniqueData
(
Start_Date,
End_Date,
Product,
isFirstOccurrence,
isLastOccurrence,
isFirstInstance,
isLastInstance
)
SELECT
Start_Date,
End_Date,
Product,
isFirstOccurrence,
isLastOccurrence,
isFirstInstance,
isLastInstance
FROM
#RawData
WHERE
isFirstOccurrence = 1 OR
isFirstInstance = 1 OR
isLastInstance = 1
ORDER BY RawData_ID, Start_Date
-- combine the first and last occurrences in any given sequence into a single row
SELECT
a.Start_Date,
ISNULL(b.Start_Date, a.End_Date) End_Date,
a.Product
FROM
#UniqueData a
LEFT JOIN
#UniqueData b ON
b.UniqueData_ID = a.UniqueData_ID + 1 AND
--b.<NaturalKey> = a.<NaturalKey> AND
a.isLastInstance <> 1
WHERE a.isFirstInstance = 1 or a.isFirstOccurrence = 1
ORDER BY a.UniqueData_ID
-- clean up
/*
DROP TABLE AdjacentValidity
DROP TABLE #RawData
DROP TABLE #UniqueData
*/
它的使用任何腳本語言更容易做到這一點 – Alexander
我認爲它可以通過分析函數解決。 –