查询其他两个日期之间的确切年份 (MS SQL)
Querying the exact years in between two other dates (MS SQL)
我正在为一项作业而苦恼,我不确定是否有解决方案。要清楚:我不是在寻找之间的年数(datediff())。
我必须连接两个表:
- Table 1 个属性:
- ID
- P_Startyear
- P_Endyear
- Table 2 具有以下属性:
- ID
- 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 它。当开始和结束之间只有 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。
假设我了解需要返回的数据,您需要的是每个 Table1
记录的列表,其中包含与 ID
属性匹配的任何 Table2
记录B_Year
值介于 P_StartYear
和 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 = 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
我正在为一项作业而苦恼,我不确定是否有解决方案。要清楚:我不是在寻找之间的年数(datediff())。
我必须连接两个表:
- Table 1 个属性:
- ID
- P_Startyear
- P_Endyear
- Table 2 具有以下属性:
- ID
- 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 它。当开始和结束之间只有 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。
假设我了解需要返回的数据,您需要的是每个 Table1
记录的列表,其中包含与 ID
属性匹配的任何 Table2
记录B_Year
值介于 P_StartYear
和 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 = 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