首页 > 解决方案 > 在 Oracle SQL 中,是否有可能有一个有效的日期查询也显示日期之间出现的行?

问题描述

我有以下表格:

产品组

|GroupID|Product Group|Product Date|
|-|-------|--------|--------|
|A|Bicycles|1/1/2018|
|A|Two-Wheels|12/1/2018|
|A|Sport Bicycles|6/1/2019|
|A|Fast Bicycles|1/1/2020|

子组

|SubgroupID|GroupID|SubGroup|SubGroupDate|
|-|-|-----|-----|
|1|A    |wheels |06/01/2015|
|2|A    |tires  |10/01/2015|
|3|A    |spokes |01/01/2017|
|4|A    |chains |01/01/2019|
|5|A    |brakes |03/01/2019|

我使用最大有效日期查询加入他们:

Select ProductName, ProductDate, tSubGroup.SubGroup, tSubGroup.SubGroupDate
FROM ProductGroup 
Left Join (SELECT SubGroupName, SubGroupDate 
            FROM SubGroup 
            WHERE SubGroup.SubGroupDate = (Select max(SubGroupDate)
                                            FROM SubGroup B
                                            where b.SubGroupName = SubGroup.SubGroupDate
                                            ) ) tSubGroup  on tSubGroup.GroupID = ProductGroup.GroupID 
                                                            and tSubGroup.SubGroupDate <= ProductGroup.ProductDate

我按预期得到以下结果:

|ProductGroup   |ProductDate    |SubGroup   |SubGroupDate|
|---|---|---|---|
|Bicycles   |01/01/2018 |Spokes |01/01/2017|
|Two-Wheels |12/01/2018 |Spokes |01/01/2017|
|Sport Bicycles |06/01/2019 |Chains |01/01/2019|
|Fast Bicycles  |01/01/2020 |Brakes |03/01/2019|

但我想要的是这样的:

|ProductGroup   |ProductDate    |SubGroup   |SubGroupDate|
|----|---|---|----|
|Bicycles   |01/01/2018 |Spokes |01/01/2017|
|Two-Wheels |12/01/2018 |Spokes |01/01/2017|
|Sport Bicycles |06/01/2019 |Chains |01/01/2019|
|Sport Bicycles |06/01/2019 |Brakes |03/01/2019|
|Fast Bicycles  |01/01/2020 |Brakes |03/01/2019|

在这些结果中,Sport Bicycles 有两行,因为 SubGroup Chains (1/1/2019) 和 Brakes (3/1/2019) 发生在 ProductGroup Two-Wheels (12/1/2018) 和 Sport Bicycles ( 2019 年 6 月 1 日)。

我不知道如何组合这两个表来获取所有行,但要确保没有添加额外的行。我尝试使用 FULL JOIN 和 LAG、LEAD、RANK 等的不同变体。我只是想弄清楚这一点。

有没有办法产生我正在寻找的结果?此外,当我完成后,还会添加三列。

感谢您的帮助。

标签: sqloracle11ganalytic-functions

解决方案


嗯。. . 我认为你想要重叠的间隔。如果是这样,lead()可以提供帮助:

select pg.*, sg.*
from (select pg.*,
             lead(productdate) over (partition by groupid order by productdate) as next_productdate
      from productgroup pg
     ) pg join
     (select sg.*,
             lead(subgroupdate) over (partition by groupid order by subgroupdate) as next_subgroupdate
      from SubGroup sg
     ) sg
     on sg.groupid = pg.groupid and
        sg.subgroupdate >= p.productdate and
        (sg.subgroupdate < p.next_productdate or p.next_productdate is null)

推荐阅读