当有多列日期时使用 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 中捕获。这发生在:
- 第 10 行 - 类别在 2016 年更改为车辆,因此介于 2014 轿车和 2018 豪华车的 ProductYear 之间。此外,由于尚未生产 Luxury Car,因此产品需要恢复为 Sedan。
- 第 13 行 - 在 2018 年和 2020 年的 ProductYear 之间的 2019 年零件更改为 Fancy Wheels。
我知道我可以执行最大生效日期查询以仅提取最近的 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
我正在构建一个 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 中捕获。这发生在:
- 第 10 行 - 类别在 2016 年更改为车辆,因此介于 2014 轿车和 2018 豪华车的 ProductYear 之间。此外,由于尚未生产 Luxury Car,因此产品需要恢复为 Sedan。
- 第 13 行 - 在 2018 年和 2020 年的 ProductYear 之间的 2019 年零件更改为 Fancy Wheels。
我知道我可以执行最大生效日期查询以仅提取最近的 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