当有多列日期时使用 SQL。我如何确定和 return 日期在其他行之间的一行?

Using SQL, when there are multiple columns with dates. how can I determine and return a row where the date is between the other rows?

我正在构建一个 table 数据仓库,需要为发生的每个更改创建一行。问题是子组中有时会发生变化,我不知道如何显示这些变化。

例如,我有 following table:

RowNumber Code CorrectedProductYear ProductYear Product CategoryYear Category PartYear Parts KeepRow
1 ABC 2012 2012 Sport Car 1995 Auto 1980 Wheels N
2 ABC 2012 2012 Sport Car 1996 Cars 1980 Wheels N
3 ABC 2012 2012 Sport Car 1998 Transport 1980 Wheels Y
4 ABC 2014 2014 Sedan 1995 Auto 1980 Wheels N
5 ABC 2014 2014 Sedan 1996 Cars 1980 Wheels N
6 ABC 2014 2014 Sedan 1998 Transport 1980 Wheels Y
7 ABC 2018 2018 Luxury Car 1995 Auto 1980 Wheels N
8 ABC 2018 2018 Luxury Car 1996 Cars 1980 Wheels N
9 ABC 2018 2018 Luxury Car 1998 Transport 1980 Wheels N
10 ABC 2016 2018 Sedan 2016 Vehicle 1980 Wheels Y
11 ABC 2018 2018 Luxury Car 2017 Motorcar 1980 Wheels Y
12 ABC 2018 2018 Luxury Car 2017 Motorcar 1980 Wheels N
13 ABC 2019 2018 Luxury Car 2017 Motorcar 2019 Fancy Wheels Y
14 ABC 2020 2020 Super Luxury Car 2017 Motorcar 2019 Fancy Wheels N
15 ABC 2020 2020 Super Luxury Car 2017 Motorcar 2019 Fancy Wheels Y

我用 'Y' 标记了 KeepRow 以显示查找结果应该是什么样子。应该是这样的:

RowNumber Code CorrectedProductYear Product CategoryYear Category PartYear Parts KeepRow
3 ABC 2012 Sport Car 1998 Transport 1980 Wheels Y
6 ABC 2014 Sedan 1998 Transport 1980 Wheels Y
10 ABC 2016 Sedan 2016 Vehicle 1980 Wheels Y
11 ABC 2018 Luxury Car 2017 Motorcar 1980 Wheels Y
13 ABC 2019 Luxury Car 2017 Motorcar 2019 Fancy Wheels Y
15 ABC 2020 Super Luxury Car 2017 Motorcar 2019 Fancy Wheels Y

在此 table 中,ProductYear 是“主要”年份。当子分组(类别和部件)的 description/year 发生变化时,需要在 ProductYear 中捕获。这发生在:

我知道我可以执行最大生效日期查询以仅提取最近的 CategoryYear 和 PartYear,但是我错过了 ProductYear 之间可能发生的更改。

我尝试了 LAG 和 LEAD 的不同变体以及 LAST_VALUE 和其他一些 Window 函数,但我卡住了,无法弄清楚这个。

我也认为仅SQL可能无法完成。如果这是更好的继续进行方式,我确实有能力做一些 SSIS。

如有任何帮助,我们将不胜感激!

谢谢。

我认为这正是您要找的东西。我不得不将它分成两个查询,因为您要为 CategoryYear 过滤一次,然后再为 PartYear 过滤一次。这可能会帮助您走上正确的道路:

SELECT RowNumber,Code,CorrectedProductYear,ProductYear,Product,CategoryYear,Category,PartYear,Parts 
FROM
(
    SELECT *, ROW_NUMBER() OVER(PARTITION BY Product order by ProductYear) RN,
        LAG(ProductYear,1) OVER(order by ProductYear) LastProdYear,
        LEAD(ProductYear,1)  OVER(order by ProductYear) NextProdYear,
        LAG(Category,1) OVER(Order by Product,ProductYear) LastCategory
    FROM Products 
) T

WHERE  CategoryYear > LastProdYear and CategoryYear < NextProdYear
and KeepRow = 'Y' and Category <> LastCategory and RN > 1

UNION ALL

SELECT RowNumber,Code,CorrectedProductYear,ProductYear,Product,CategoryYear,Category,PartYear,Parts 
FROM
(
    SELECT *, ROW_NUMBER() OVER(PARTITION BY Product order by ProductYear) RN,
        LAG(ProductYear,1) OVER(order by ProductYear) LastProdYear,
        LEAD(ProductYear,1)  OVER(order by ProductYear) NextProdYear,
        LAG(Parts,1) OVER(Order by Product,ProductYear) LastParts
    FROM Products 
) T
WHERE  PartYear > LastProdYear and PartYear < NextProdYear
and KeepRow = 'Y' and Parts <> LastParts and RN > 1