1

다음은 이야기입니다. 저는 위험한 액체 화학 물질을 유용한 화학 물질로 재활용하는 회사에서 일하고 있습니다. 이 과정의 일부는 재활용 과정의 각 부분이 완료 될 때 한 탱크에서 다른 탱크로 물질을 옮기는 것입니다. 이 탱크는 탱크 농장, 증류 시스템의 일부, 철도 차량 또는 탱커 트럭에 있습니다. 내가 배정 된 과제는 관리자가 모든 탱크를 데리러 처분하거나 판매 될 때까지 모든 탱크를 통해 해당 물질의 움직임을 추적 할 수있는 쿼리를 작성하는 것이 었습니다. 내 시간 전에 데이터베이스가 10 년 전에 구축되었으므로 데이터는 내가 작업해야하는 모든 것 (즉, 작업하기 쉽도록 변경할 수 없음)입니다. 날짜와 탱크 이름을 사용하는 재귀 T-SQL 쿼리

지금 테이블 구조 :이 노력에 자신을 빌려 열은 다음과 같습니다

  • OpenDate (날 빈 탱크를 수신하기 시작 재료)
  • CosedDate (탱크는 날짜를 SouceTank 폐쇄, 비우기, 신소재 준비)
  • DestinationTank (자재가 이전 된 탱크)
  • ProductName (유효성을 검사하기 위해 이것을 추가합니다. 섞여 라. 일부는 있습니다. 알고리즘이 제대로 작동하지 않으면 혼합 할 수없는 문제가 발생할 수 있습니다.)

모든 탱크는 OpenDate를 갖지만 여전히 채워지거나 발송 대기중인 탱크는 닫힌 날짜가 없습니다 . 대부분 탱크는 화학적으로 불가지론 적입니다. 어떤 비어있는 탱크도 모든 화학 물질에 사용할 수 있습니다. 1에서 10 개의 움직임이 예상 될 수 있습니다.

재귀 CTE T-SQL 알고리즘을 사용해 보았지만 SourceTank의 CosedDate가 DestinationTank의 OpenDate와 CosedDate 사이에 있거나 일치하는 DestinationTank와 SourceTank를 일치 시키려고하면 길을 잃었습니다. 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 

여기에 내가 뭘하려합니다. 내가 예상 한 결과가 어떻게 보일지 알 수 없기 때문에이 얼마나 유용 모르겠어요

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-server-2014'. 구문과 기능의 차이가 종종 답변에 영향을 미칩니다. 'tsql'은 선택 항목을 좁히지 만 데이터베이스는 지정하지 않습니다. – HABO

+0

올바른 결과는 무엇입니까? 우리는 모든 종류의 질의를 생성 할 수 있지만 제공된 데이터로 인해 어떤 결과가 기대되는지 알고 있다면 가장 좋습니다. * 우리가 제안한 쿼리를 검증 할 수 있으므로 작업이 줄어 듭니다. * –

답변

1

있습니다 .. NULL ClosingDate을 처리하는 방법을 알고하지 않았다, 그러나 그것은 도움이 있습니다. 나는 날짜를 이해하려고 노력 했으므로 경로 열로 연결된 것을 볼 수 있습니다. 나는 또한 어디에서 시작해야할지 확신하지 못했기 때문에 각 탱크의 초기 시작일을 추측했다.

SQL Fiddle

MS SQL 서버 2014 스키마 설정 : 1

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') 
; 

검색어 :

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_ 이미 친절하게 제공하여 각 전송과 관련된 정보를 추가하여 관리에보다 유용하게 사용할 수있게 할 것입니다. 고맙습니다 Used_By_ 이미! –