好的,这就是故事:我在一家公司工作,将危险的液体化学品回收成有用的化学品。该过程的一部分涉及在回收过程的每个部分完成时将这些材料从一个罐移动到另一个罐。这些罐位于我们的罐区,蒸馏系统的一部分,铁路车辆或油罐车中。我被分配的任务是写一个查询,允许经理拿起任何油箱,并跟踪每个油箱的物料移动,直到它被处置或出售。数据库是在大约10年前,在我的时间之前建立的,所以数据是我必须处理的(即不能改变它以使其更容易使用)。
现在表格结构:适合这项努力的专栏是:
所有坦克都将有一个OpenDate,但坦克仍在装满或等待运出,因此没有关闭日期。大多数情况下,坦克是化学不可知的 - 在任何情况下,任何空罐都可用于任何化学品。可以预期从1到10次移动。
我尝试使用递归CTE T-SQL算法,但很快就试图将SourceTank与匹配的DestinationTank匹配,其中SourceTank的CosedDate位于DestinationTank的OpenDate和CosedDate之间,或者至少等于或等于如果还没有关闭,那么DestinationTank的OpenDate。
示例数据:
SourceTank StartDate ClosedDate DestinationTank ProductName
------------------------------------------------------------------------
TNK01-5 08/03/2017 08/10/2017 TNK30-6 Fuels
TNK01-5 08/07/2017 08/10/2017 TNK40-6 Fuels
TNK01-5 07/20/2017 07/31/2017 TNK01-5 Incin
TNK01-5 08/10/2017 08/17/2017 TNK30-6 Incin
TNK01-5 08/12/2017 08/17/2017 TNK30-6 Fuels
TNK03-5 08/13/2017 08/22/2017 TNK30-6 IBAC feed
TNK07-5 08/11/2017 08/17/2017 TNK40-6 Incin
TNK07-5 08/14/2017 08/29/2017 TNK40-6 Fuels
TNK07-5 07/15/2017 08/10/2017 TNK30-6 Picoline Cut
TNK07-5 08/03/2017 08/10/2017 TNK02-5 Pico 2nd Pass
TNK07-5 08/06/2017 08/17/2017 TNK40-6 Fuels
TNK08-5 08/05/2017 08/10/2017 TNK40-6 Fuels
TNK08-5 08/07/2017 08/08/2017 TNK30-6 Fuels
TNK08-5 08/10/2017 08/22/2017 TNK40-6 Water
TNK08-5 07/24/2017 08/10/2017 TNK02-5 Picoline Cut
TNK09-10 07/20/2017 NULL TNK30-6 Picoline Crude
TNK09-10 07/21/2017 08/04/2017 TNK30-6 Picoline Crude
TNK09-10 08/02/2017 08/10/2017 TNK30-6 Cyclo Waste
TNK09-10 08/05/2017 08/10/2017 TNK30-6 Cyclo Waste
TNK09-10 08/07/2017 08/10/2017 TNK30-6 Cyclo Waste
TNK09-10 08/04/2017 08/10/2017 TNK30-6 Cyclo Waste
TNK09-10 08/15/2017 08/22/2017 TNK30-6 IBAC feed
TNK09-10 08/11/2017 08/17/2017 TNK30-6 IBAC feed
TNK09-10 08/12/2017 08/17/2017 TNK30-6 IBAC feed
TNK30-6 08/08/2017 08/29/2017 TNK30-6 Cyclo Waste
TNK40-6 08/13/2017 08/22/2017 TNK30-6 IBAC:PRODUCT
TNK41-6 08/14/2017 09/27/2017 NATX25496 IBAC:PRODUCT
TNK51-12 07/26/2017 09/15/2017 TNK30-6 CYCLO Product
TNK62-12 07/28/2017 09/12/2017 TNK30-6 NON-RCRA NMP
TNK74-12 07/29/2017 NULL TNK30-6 Picoline Crude
TNK91-8 08/03/2017 08/22/2017 TNK08-5 Picoline Prod
这是我尝试过的。我不知道如何处理NULL ClosingDate ..
WITH TanksCTE AS (
SELECT [TrackingNum]
,[TblTankTracking].[TankID]
,[StartDate]
,[TblTankTracking].[ProductID]
,[ClosedDate]
,[Destination]
FROM [MAFTS].[Laboratory].[TblTankTracking]
UNION ALL
SELECT TCTE.[TrackingNum]
,TRACK.[TankID]
,TRACK.[StartDate]
,TRACK.[ProductID]
,TRACK.[ClosedDate]
,TRACK.[Destination]
FROM TanksCTE AS TCTE INNER JOIN
[MAFTS].[Laboratory].[TblTankTracking] TRACK
ON TCTE.[TankID] = TRACK.[Destination]
AND TRACK.[ClosedDate] BETWEEN TCTE.[StartDate] AND TCTE.[ClosedDate]
)
SELECT * FROM TanksCTE
option (maxrecursion 0)
答案 0 :(得分:1)
我不确定这会有多大用处,因为我不知道预期的结果应该是什么样的,但它可能有所帮助。我试图理解日期,这就是为什么你会看到它们连接成一个路径列。我也不确定从哪里开始,所以我猜到每个坦克最早的开始日期。
MS SQL Server 2014架构设置:
CREATE TABLE Table1
([SourceTank] varchar(8), [StartDate] datetime, [ClosedDate] datetime, [DestinationTank] varchar(9), [ProductName] varchar(14))
;
INSERT INTO Table1
([SourceTank], [StartDate], [ClosedDate], [DestinationTank], [ProductName])
VALUES
('TNK01-5', '2017-08-03 00:00:00', '08/10/2017', 'TNK30-6', 'Fuels'),
('TNK01-5', '2017-08-07 00:00:00', '08/10/2017', 'TNK40-6', 'Fuels'),
('TNK01-5', '2017-07-20 00:00:00', '07/31/2017', 'TNK01-5', 'Incin'),
('TNK01-5', '2017-08-10 00:00:00', '08/17/2017', 'TNK30-6', 'Incin'),
('TNK01-5', '2017-08-12 00:00:00', '08/17/2017', 'TNK30-6', 'Fuels'),
('TNK03-5', '2017-08-13 00:00:00', '08/22/2017', 'TNK30-6', 'IBAC feed'),
('TNK07-5', '2017-08-11 00:00:00', '08/17/2017', 'TNK40-6', 'Incin'),
('TNK07-5', '2017-08-14 00:00:00', '08/29/2017', 'TNK40-6', 'Fuels'),
('TNK07-5', '2017-07-15 00:00:00', '08/10/2017', 'TNK30-6', 'Picoline Cut'),
('TNK07-5', '2017-08-03 00:00:00', '08/10/2017', 'TNK02-5', 'Pico 2nd Pass'),
('TNK07-5', '2017-08-06 00:00:00', '08/17/2017', 'TNK40-6', 'Fuels'),
('TNK08-5', '2017-08-05 00:00:00', '08/10/2017', 'TNK40-6', 'Fuels'),
('TNK08-5', '2017-08-07 00:00:00', '08/08/2017', 'TNK30-6', 'Fuels'),
('TNK08-5', '2017-08-10 00:00:00', '08/22/2017', 'TNK40-6', 'Water'),
('TNK08-5', '2017-07-24 00:00:00', '08/10/2017', 'TNK02-5', 'Picoline Cut'),
('TNK09-10', '2017-07-20 00:00:00', NULL, 'TNK30-6', 'Picoline Crude'),
('TNK09-10', '2017-07-21 00:00:00', '08/04/2017', 'TNK30-6', 'Picoline Crude'),
('TNK09-10', '2017-08-02 00:00:00', '08/10/2017', 'TNK30-6', 'Cyclo Waste'),
('TNK09-10', '2017-08-05 00:00:00', '08/10/2017', 'TNK30-6', 'Cyclo Waste'),
('TNK09-10', '2017-08-07 00:00:00', '08/10/2017', 'TNK30-6', 'Cyclo Waste'),
('TNK09-10', '2017-08-04 00:00:00', '08/10/2017', 'TNK30-6', 'Cyclo Waste'),
('TNK09-10', '2017-08-15 00:00:00', '08/22/2017', 'TNK30-6', 'IBAC feed'),
('TNK09-10', '2017-08-11 00:00:00', '08/17/2017', 'TNK30-6', 'IBAC feed'),
('TNK09-10', '2017-08-12 00:00:00', '08/17/2017', 'TNK30-6', 'IBAC feed'),
('TNK30-6', '2017-08-08 00:00:00', '08/29/2017', 'TNK30-6', 'Cyclo Waste'),
('TNK40-6', '2017-08-13 00:00:00', '08/22/2017', 'TNK30-6', 'IBAC:PRODUCT'),
('TNK41-6', '2017-08-14 00:00:00', '09/27/2017', 'NATX25496', 'IBAC:PRODUCT'),
('TNK51-12', '2017-07-26 00:00:00', '09/15/2017', 'TNK30-6', 'CYCLO Product'),
('TNK62-12', '2017-07-28 00:00:00', '09/12/2017', 'TNK30-6', 'NON-RCRA NMP'),
('TNK74-12', '2017-07-29 00:00:00', NULL, 'TNK30-6', 'Picoline Crude'),
('TNK91-8', '2017-08-03 00:00:00', '08/22/2017', 'TNK08-5', 'Picoline Prod')
;
查询1 :
with TankStart as (
select
*
, row_number() over(partition by SourceTank order by StartDate ASC) as rn
from Table1
)
, TankPaths as (
SELECT
T.SourceTank
, T.DestinationTank
, T.StartDate
, T.ClosedDate
, T.ProductName
, CAST(T.DestinationTank AS varchar(max))
+ ' '
+ convert(varchar(10),T.ClosedDate,120)
AS Pathway
FROM TankStart T
WHERE T.rn = 1
union all
SELECT
T1.SourceTank
, T1.DestinationTank
, T1.StartDate
, T1.ClosedDate
, T1.ProductName
, M.Pathway
+ ' '
+ convert(varchar(10),T1.StartDate,120)
+ ', '
+ CAST(T1.DestinationTank AS varchar(max))
+ ', '
+ convert(varchar(10),T1.ClosedDate,120)
FROM Table1 T1
INNER JOIN TankPaths M ON M.DestinationTank = T1.SourceTank
AND M.ClosedDate <= T1.StartDate
where T1.SourceTank <> T1.DestinationTank
)
select *
from TankPaths
order by 1, 2, Pathway
<强> Results 强>:
| SourceTank | DestinationTank | StartDate | ClosedDate | ProductName | Pathway |
|------------|-----------------|----------------------|----------------------|----------------|------------------------------------------------------------------------------------|
| TNK01-5 | TNK01-5 | 2017-07-20T00:00:00Z | 2017-07-31T00:00:00Z | Incin | TNK01-5 2017-07-31 |
| TNK01-5 | TNK30-6 | 2017-08-03T00:00:00Z | 2017-08-10T00:00:00Z | Fuels | TNK01-5 2017-07-31 2017-08-03, TNK30-6, 2017-08-10 |
| TNK01-5 | TNK30-6 | 2017-08-10T00:00:00Z | 2017-08-17T00:00:00Z | Incin | TNK01-5 2017-07-31 2017-08-10, TNK30-6, 2017-08-17 |
| TNK01-5 | TNK30-6 | 2017-08-12T00:00:00Z | 2017-08-17T00:00:00Z | Fuels | TNK01-5 2017-07-31 2017-08-12, TNK30-6, 2017-08-17 |
| TNK01-5 | TNK40-6 | 2017-08-07T00:00:00Z | 2017-08-10T00:00:00Z | Fuels | TNK01-5 2017-07-31 2017-08-07, TNK40-6, 2017-08-10 |
| TNK03-5 | TNK30-6 | 2017-08-13T00:00:00Z | 2017-08-22T00:00:00Z | IBAC feed | TNK30-6 2017-08-22 |
| TNK07-5 | TNK30-6 | 2017-07-15T00:00:00Z | 2017-08-10T00:00:00Z | Picoline Cut | TNK30-6 2017-08-10 |
| TNK08-5 | TNK02-5 | 2017-07-24T00:00:00Z | 2017-08-10T00:00:00Z | Picoline Cut | TNK02-5 2017-08-10 |
| TNK09-10 | TNK30-6 | 2017-07-20T00:00:00Z | (null) | Picoline Crude | (null) |
| TNK30-6 | TNK30-6 | 2017-08-08T00:00:00Z | 2017-08-29T00:00:00Z | Cyclo Waste | TNK30-6 2017-08-29 |
| TNK40-6 | TNK30-6 | 2017-08-13T00:00:00Z | 2017-08-22T00:00:00Z | IBAC:PRODUCT | TNK01-5 2017-07-31 2017-08-07, TNK40-6, 2017-08-10 2017-08-13, TNK30-6, 2017-08-22 |
| TNK40-6 | TNK30-6 | 2017-08-13T00:00:00Z | 2017-08-22T00:00:00Z | IBAC:PRODUCT | TNK30-6 2017-08-22 |
| TNK41-6 | NATX25496 | 2017-08-14T00:00:00Z | 2017-09-27T00:00:00Z | IBAC:PRODUCT | NATX25496 2017-09-27 |
| TNK51-12 | TNK30-6 | 2017-07-26T00:00:00Z | 2017-09-15T00:00:00Z | CYCLO Product | TNK30-6 2017-09-15 |
| TNK62-12 | TNK30-6 | 2017-07-28T00:00:00Z | 2017-09-12T00:00:00Z | NON-RCRA NMP | TNK30-6 2017-09-12 |
| TNK74-12 | TNK30-6 | 2017-07-29T00:00:00Z | (null) | Picoline Crude | (null) |
| TNK91-8 | TNK08-5 | 2017-08-03T00:00:00Z | 2017-08-22T00:00:00Z | Picoline Prod | TNK08-5 2017-08-22 |