【问题标题】:Querying the exact years in between two other dates (MS SQL)查询其他两个日期之间的确切年份(MS SQL)
【发布时间】:2015-04-30 06:42:08
【问题描述】:

我正在为一项任务而苦苦挣扎,我不确定是否有解决方案。需要明确的是:我不是在寻找之间的年数(datediff())。

我必须加入两个表:

  • 带有属性的表 1:
    • 身份证
    • P_Startyear
    • P_Endyear
  • 带有属性的表 2:
    1. 身份证
    2. B_Year

表格中有更多属性,但对于这个问题,它们并不重要。

例如: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 它。这应该在 start 和 endyear 之间只有 1 年的情况下有效,但在有多年的情况下无效,因为您只能在 if-else case 语句(布尔值)中添加一个值。

错误测试代码示例:

-- 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 Server 2008。

【问题讨论】:

  • 请发布样本数据的预期结果。
  • 添加了样本数据的结果。如您所见,它只返回与 Startyear 或 endyear 不匹配的 B_years。

标签: sql-server-2008 case datediff datepart


【解决方案1】:

假设我了解需要返回的数据,您需要的是每个 Table1 记录的列表,其中包含与 ID 属性匹配且其 B_Year 值介于 @987654325 之间的任何 Table2 记录@ 和 P_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

【讨论】:

  • 谢谢,这正是我想要的!这对我完成解决方案有很大帮助。 :)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-10-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-07-25
  • 1970-01-01
相关资源
最近更新 更多