0

課題に苦労していますが、解決策があるかどうかわかりません。明確にするために:私はその間の年数(datediff())を探していません。

2 つのテーブルを結合する必要があります。

  • 属性を含む表 1:
    • ID
    • P_開始年
    • P_Endyear
  • 属性を含む表 2:
    1. ID
    2. 耳で

表にはさらに多くの属性がありますが、この質問ではそれらは重要ではありません。

例: P_Startyear は 2008 で、P_endyear は 2010 です。すべての P_year は B_Year と一致する必要があります。そうでない場合は、P_row を返す必要があります。ただし、問題は、P_startyear と P__endyear (この場合は 2009 年) の間の年もチェックする必要があることです。したがって、2009年に一致するB_yearがあるかどうかも確認する必要があり、そうでない場合は、行を返す必要があります(他の一致と一緒に)。

P_startyear と 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 

私は temp_table を埋めて年を取得しようとしましたが、日付の違いを確認してから、IF-Else Case を実行しました。これは、開始年と終了年の間に 1 年しかない場合は機能しますが、複数の年がある場合は機能しません。if-else case ステートメント (ブール値) に値を 1 つしか追加できないためです。

間違ったテストコードの例:

-- 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

Case ステートメントが正しくないことは認識していますが、考えられる解決策を示すためのものです。私が作ったタイプミスをお許しください。オランダの名前とプライバシーの問題により、すべての名前を変更する必要がありました。できる限り詳しく説明するよう心がけておりますが、ご不明な点がございましたら、遠慮なくお尋ねください。これが解決できないと確信している場合でも、助けていただければ幸いです。Microsoft SQL サーバー 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 = IDTestYear = 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 に答える