0

I am struggling with an assignment and I am not sure if there is a solution. To be clear: I am not looking for the amount of years in between(datediff()).

I have to join two tables:

  • Table 1 with attributes:
    • ID
    • P_Startyear
    • P_Endyear
  • Table 2 with attributes:
    1. ID
    2. B_Year

There are more attributes in the tables, but for this question they do not matter.

As example: The P_Startyear is 2008 and the P_endyear is 2010. Every P_year has to match a B_Year. If not, then the P_row has to be returned. The problem however is that I also have to check the years in between the P_startyear and P__endyear (in this case 2009). So I also have to check if 2009 has a matching B_year and if that is not the case, the row has to be returned(together with the other matches).

I have already wrote some working code to check matches of the P_startyear and P_endyear:

SELECT 
    P.ID,
    YEAR(P.P_Startyear) as [P_Startyear],
    YEAR(P.P_Endyear) as [P_Endyear],
    B.B_Year        
FROM Table1 P
LEFT OUTER Join Tabl2 B
on P.ID = B.ID
Where 
(YEAR(P.P_Startyear) <> B.B_Year
AND YEAR(P.P_Endyear) <> B.B_Year
-- Check if the year(s) in between startyear and end year match a B.B_year with the same ID).

Result:
CaseIdentifier  P_Startyear P_Endyear   B_Year
DCM_TEST        2011    2012    2010                                                            
DCm2011____25   2011    2012    2010                                                            
DCm2011____71   2012    2012    2009                                                            
DCm2011____71   2012    2012    2011                                                            
DCm2013____37   2013    2014    2007                                                            
DCm2013____37   2013    2014    2009                                                            
DCm2013____37   2013    2014    2012                                                            
DCm2013____56   2021    2022    2012                                                            
DCm2013____8    2012    2012    2010                                                            
DCm2013____9    2012    2012    2010 

I have tried to get the year in between by filling a temp_table, check the datedifference and then IF-Else Case it. This should work when there is only 1 year in between the start and endyear, but not when there are multiple years, because you can only add one value in an if-else case statement(Boolean).

Example of the wrong testcode:

-- Create a Temp_table list with startdates per P_ID.
SELECT 
       p.ID,
       p.P_Startyear as [Startyear1],
       p.P_Startyear as [Startyear2],
       p.P_Startyear as [Startyear3],
       p.P_Startyear as [Startyear4],
       p.P_Startyear as [Startyear5],
INTO #Years
FROM Table1 as p       
--===================================================================== 

Select 
       DATEDIFF(year,P_Startyear, P_Endyear) as DiffYears,
       J.Startyear1,
       J.Startyear2,   
       J.Startyear3,           
       J.Startyear4,  
       J.Startyear5,                               
-- Case if 1 year then Startyear1 +1, if 2 years Startyear1 +1 and Startyear2 +2 etc.
        case
         when DATEDIFF(year,P_Startyear, P_Endyear) = '1' then Startyear1 +1    
         when DATEDIFF(year,P_Startyear, P_Endyear) = '2' then Startyear1 +1 AND Startyear2 +2
         when DATEDIFF(year,P_Startyear, P_Endyear) = '3' then J.Startyear1 +1 AND J.Startyear2 +2 AND J.Startyear3 +3
         when DATEDIFF(year,P_Startyear, P_Endyear) = '4' then J.Startyear1 +1 AND J.Startyear2 +2 AND J.Startyear3 +3 AND J.Startyear4 +4
         when DATEDIFF(year,P_Startyear, P_Endyear) = '4' then J.Startyear1 +1 AND J.Startyear2 +2 AND J.Startyear3 +3 AND J.Startyear4 +4 AND J.Startyear5 +5
            end as [Startyear]

FROM  Table 1 as p
Join #Years as J
On P.ID = J.ID  
Drop table #Years

I am aware that the Case statement is incorrect, but it is just to show the potentional solution. Excuse me for any typo's I have made. I had to rename everything due to Dutch names and privacy matters. I have tried to explain the situation as comprehensive as possible, but if you have any questions, don't hesitate to ask them. Any help is appreciated, even if you are sure this can not be solved I would like to hear it. I am working with Microsoft SQL server 2008.

4

1 回答 1

0

假设我了解需要返回的数据,那么您需要的是每个记录的列表,其中包含与属性匹配的Table1任何记录,并且其值介于和之间,包括在内。Table2IDB_YearP_StartYearP_EndYear

如果您可以转换此记录:

 ID            P_Startyear P_Endyear  
 -----------------------------------
 DCM_TEST         2011      2015   

...进入这样的记录:

 ID            P_Startyear P_Endyear  TestYear
 ---------------------------------------------
 DCM_TEST         2011      2015        2011
 DCM_TEST         2011      2015        2012
 DCM_TEST         2011      2015        2013
 DCM_TEST         2011      2015        2014
 DCM_TEST         2011      2015        2015

Table2...您可以看到,对ID = ID和进行左连接非常容易TestYear = B_Year

我认为您可以使用递归 CTE 来做到这一点。它看起来像这样(免责声明:这是从内存中完成的):

 ;
 WITH P
 AS  (
    SELECT ID
       ,   P_StartYear
       ,   P_EndYear
       ,   TestYear = P_StartYear
    FROM   Table1
    UNION ALL
    SELECT ID
       ,   P.P_StartYear
       ,   P.P_EndYear
       ,   TestYear = P.TestYear + 1
    FROM   P
    WHERE  P.TestYear < P.P_EndYear
)
SELECT  P.*
   ,    Table2.*
FROM    P
   LEFT JOIN Table2
         ON  P.ID = Table2.ID
         AND P.TestYear = Table2.B_Year
于 2015-02-27T22:56:59.037 回答