SQL Server Obtain specific date from table

8dtrkrch  于 2023-05-05  发布在  其他
关注(0)|答案(4)|浏览(151)

I have the following 2 tables:

Process table
| PROCESS_ID | PROCESS_NAME |
| ------------ | ------------ |
| A_0001 | A1 |
| A_0002 | A2 |
| A_0003 | A3 |

Phase Tracking Table

PHASE_IDPROCESS_IDPHASE_NAMEDATE
1A_0001Draft10/01/2023
2A_0001Review13/01/2023
3A_0001Investigation15/01/2023
4A_0001Review18/01/2023
5A_0002Draft10/01/2023
6A_0002Review13/01/2023
7A_0002Draft15/01/2023
8A_0003Draft10/01/2023
9A_0003Review11/01/2023

Then, what I need to obtain is the latest phase for each process but with the min date for that phase in case the phase is not unique. For the data of the two previous tables, I would like to obtain the following result:

PROCESS_IDPROCESS_NAMEPHASE_NAMEINITIAL DATE
A_0001A1Review13/01/2023
A_0002A2Draft10/01/2023
A_0003A3Review11/01/2023

As you can see, for process_id = A_0001 , the last phase is Review, but as we have a previous Review phase, we need to obtain the date for that phase, so 13/01/2023 instead of 18/01/2023

I've tried several queries already with HAVING and GROUP PY clauses.

mzillmmw

mzillmmw1#

Here's a straightforward way of thinking about the problem. You'll need to know which phase is the current state. Once that's determined it's easy to filter for all rows with that same state and then group to get the minimum date:

with PhaseData as (
    select *,
        first_value(PHASE_NAME) over (
             partition by PROCESS_ID order by "DATE" desc) as mr_PHASE_NAME
    from PhaseTracking
)
select pd.PROCESS_ID,
    min(p.PROCESS_NAME) as PROCESS_NAME, min(pd.PHASE_NAME) as PHASE_NAME,
    min("DATE") AS INITIAL_DATE
from PhaseData as pd inner join Process as p on p.PROCESS_ID = pd.PROCESS_ID
where pd.PHASE_NAME = pd.mr_PHASE_NAME
group by pd.PROCESS_ID;
t9aqgxwy

t9aqgxwy2#

Here is an option using with window functions min() over() and row_number() in concert with a WITH TIES

Example or dbFiddle

Select top 1 with ties 
       A.Process_ID
      ,B.Process_Name
      ,A.PHASE_NAME
      ,InitialDate = min(date) over (partition by A.PROCESS_ID,A.PHASE_NAME) 
 From TrackingTable A
 Join ProcessTable       B  on A.PROCESS_ID = B.PROCESS_ID
 Order By row_number() over (partition by A.PROCESS_ID order by Date desc)

Results

xtfmy6hx

xtfmy6hx3#

SELECT p.PROCESS_ID
     , pr.PROCESS_NAME
     , p.PHASE_NAME
     , MIN(p.DATE) InitialDate
FROM PhaseTracking p
INNER JOIN (
            SELECT p1.*
            FROM PhaseTracking p1
            INNER JOIN (
                        SELECT PROCESS_ID  , MAX(PHASE_ID) PHASE_ID
                        FROM PhaseTracking pt 
                        GROUP BY PROCESS_ID
                     ) pt ON pt.PHASE_ID = p1.PHASE_ID AND pt.PROCESS_ID = p1.PROCESS_ID
            ) p2 ON p2.PROCESS_ID = p.PROCESS_ID AND p2.PHASE_NAME = p.PHASE_NAME
INNER JOIN Process pr ON pr.PROCESS_ID = p.PROCESS_ID
GROUP BY p.PROCESS_ID
     , p.PHASE_NAME
     , pr.PROCESS_NAME
eeq64g8w

eeq64g8w4#

first step i find PHASE_NAME and find min date per PHASE_NAME

;with _list as (
 SELECT PT.PROCESS_ID ,PROCESS_NAME
,LAST_VALUE(PHASE_NAME) OVER(partition by PT.PROCESS_ID 
ORDER BY  DATE_  desc) as Ls_PHASE_NAME
 ,row_number() OVER(partition by PT.PROCESS_ID ORDER BY DATE_  desc) as rw 
 FROM Phase_Tracking PT
 INNER JOIN Process c on c.PROCESS_ID = PT.PROCESS_ID
)
select *
from (
     SELECT b.PROCESS_ID,a.PROCESS_NAME,PHASE_NAME,b.DATE_ [INITIAL DATE]
     ,ROW_NUMBER() over(partition by a.PROCESS_ID order by b.DATE_) as rw
     from _list a
     inner join Phase_Tracking b on a.PROCESS_ID=b.PROCESS_ID
     and a.Ls_PHASE_NAME=b.PHASE_NAME  and a.rw=1
)a
 where a.rw=1
create Table Phase_Tracking  (PHASE_ID int,PROCESS_ID varchar(100)
,PHASE_NAME varchar(100),DATE_ date)  
 
Insert Into Phase_Tracking Values (1,'A_0001','Draft','10/01/2023')
Insert Into Phase_Tracking Values (2,'A_0001','Review','13/01/2023')
Insert Into Phase_Tracking Values (3,'A_0001','Investigation','15/01/2023')
Insert Into Phase_Tracking Values (4,'A_0001','Review','18/01/2023')
Insert Into Phase_Tracking Values (5,'A_0002','Draft','10/01/2023')
Insert Into Phase_Tracking Values (6,'A_0002','Review','13/01/2023')
Insert Into Phase_Tracking Values (7,'A_0002','Draft','15/01/2023')
Insert Into Phase_Tracking Values (8,'A_0003','Draft','10/01/2023')
Insert Into Phase_Tracking Values (9,'A_0003','Review','11/01/2023')
 
create Table Process   (PROCESS_ID varchar(100),PROCESS_NAME varchar(100))  
Insert Into Process  Values  ('A_0001','A1')
Insert Into Process  Values('A_0002','A2')
Insert Into Process  Values('A_0003','A3')

相关问题