1

好的,這裏是故事:我爲一家公司工作,該公司將有害液體化學品回收成有用的化學品。這一過程的一部分涉及將這些材料從一個罐移到另一個罐,因爲回收過程的每個部分都已完成。這些坦克要麼在我們的坦克農場,在蒸餾系統的一部分,在有軌電車,或油罐卡車。我分配的任務是寫一個查詢,讓經理拿起任何坦克,並跟隨該材料通過每個坦克的運動,直到它被處置或出售。這個數據庫大概是在10年前建立起來的,所以我只需要處理數據(即不能改變數據庫使其更容易處理)。遞歸T-SQL查詢使用日期和坦克名稱

查閱表的結構:即適合這種努力中列有:

  • SouceTank
  • Opendate裏(這一天空罐開始接收材料)
  • CosedDate(罐是日期關閉,清空,並準備好新的材料)
  • DestinationTank(坦克的材料被移動到)
  • ProductName(我添加這個驗證動作。許多材料不能混合。有些是。如果算法運行不正常,那麼不能混合的問題就會出現問題。)

所有的坦克都會有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

請與我們分享您的輸入參數是什麼(如果有的話)。你只是想在坦克的基礎上做這個查詢),以及你的預期輸出應該是什麼。如果您已經開始了一個不適用的查詢,那麼這個查詢可能也很有用。 – pcdev

+0

請閱讀[this](http://spaghettidba.com/2015/04/24/how-to-post-a-t-sql-question-on-a-public-forum/)瞭解一些關於改善問題的提示。使用適當的軟件(MySQL,Oracle,DB2,...)和版本(例如, '的SQL服務器2014'。語法和功能的差異往往會影響答案。請注意,'tsql'縮小了選擇範圍,但不指定數據庫。 – HABO

+0

什麼是正確的結果?雖然我們可以產生各種查詢,但最好能通過提供的數據知道您期望的結果)。 *它還使我們能夠驗證我們建議的任何查詢,所以減少對您的查詢。* –

回答

1

我不知道這是多麼有用將是因爲我不知道預期的結果應該是什麼樣子,但它可能幫助。我試圖理解日期,這就是爲什麼你會看到它們連接成一個通路列。我也不確定從哪裏開始,所以我猜測每個坦克的最早開始時間。

SQL Fiddle

的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 | 
+0

我喜歡這個解決方案。我將不得不研究一下,看看它是否能爲我們完成這項工作。 –

+0

用戶可以從任何坦克開始,也可以在此過程的任何階段開始。所以,他/她可能會在中間的某個地方找到材料從那裏出發的地方。 –

+0

未來的訪問者會知道,我將採用@Used_By_Already提供的這個框架,並添加與每個傳輸相關的信息,以使其對我們的管理更加有用。謝謝Used_By_Already! –