SQL - 根据其中两个中的(不同)最新日期加入三个表
SQL - join three tables based on (different) latest dates in two of them
使用 Oracle SQL Developer,我有三个 table 需要加入一些常用数据。
感谢对此的任何帮助!
请参阅 https://i.stack.imgur.com/f37Jh.png 了解输入和所需的输出(table 格式不适用于所有 table)。
这些 table 是为了匿名化而编造的,实际上包含具有数百万条目的其他数据,但您可以将它们视为代表:
- 产品 = 杂货店的主要产品类别。
- Subproduct = 上述产品的子类别。每次 table 更新时,主要产品类别可能会丢失或获得一些分配给它的新产品。例如。你可以看到从五月到六月,拉肉进来了,鱼汤被扔掉了。
- 问题 = 产品状态,例如,如果苹果上有褐色斑点,则表明它是坏的..
我需要找的是:对每个P_NAME,找到最新更新的一组子产品(SP_ID和SP_NAME ),并将该信息附加到最新更新的问题状态 (STATUS_FLAG)。
请注意,每个主要产品类别都会在不同的场合更新其子产品集,即 1234 和 5678 可能在不同的日期“最新更新”。
我尝试了多次查询,但每次都失败了。我正在使用 SELECT
、LEFT OUTER JOIN
、JOIN
、MAX
和 GROUP BY
.
的组合
最新尝试,它给出了前两个 table 的组合,但缺少第三个:
SELECT
PRODUCT.P_NAME,
SUBPRODUCT.SP_PRODUCT_ID, SUBPRODUCT.SP_NAME, SUBPRODUCT.SP_ID, SUPPRODUCT.SP_VALUE_DATE
FROM SUBPRODUCT
LEFT OUTER JOIN PRODUCT ON PRODUCT.P_ID = SUBPRODUCT.SP_PRODUCT_ID
JOIN(SELECT SP_PRODUCT_ID, MAX(SP_VALUE_DATE) AS latestdate FROM SUBPRODUCT GROUP BY SP_PRODUCT_ID) sub ON
sub.SP_PRODUCT_ID = SUBPRODUCT.SP_PRODUCT_ID AND sub.latestDate = SUBPRODUCT.SP_VALUE_DATE;
尝试查找具有最大值的行是一种常见的 SQL 模式 - 您可以使用连接来完成,就像您的示例一样,但通常使用子查询或 window函数。
相关子查询示例
select
PRODUCT.P_NAME,
SUBPRODUCT.SP_PRODUCT_ID, SUBPRODUCT.SP_NAME, SUBPRODUCT.SP_ID, SUPPRODUCT.SP_VALUE_DATE,
ISSUES.STATUS_FLAG, ISSUES.STATUS_LAST_UPDATED
from PRODUCT
join SUBPRODUCT
on PRODUCT.P_ID = SUBPRODUCT.SP_PRODUCT_ID
and SUBPRODUCT.SP_VALUE_DATE = (select max(S2.SP_VALUE_DATE) as latestDate
from SUBPRODUCT S2
where S2.SP_PRODUCT_ID = SUBPRODUCT.SP_PRODUCT_ID)
join ISSUES
on ISSUES.ISSUE_ID = SUBPRODUCT.SP_ID
and ISSUES.STATUS_LAST_UPDATED = (select max(I2.STATUS_LAST_UPDATED) as latestDate
from ISSUES I2
where I2.ISSUE_ID = ISSUES.ISSUE_ID)
Window 函数/内联视图示例
select
PRODUCT.P_NAME,
S.SP_PRODUCT_ID, S.SP_NAME, S.SP_ID, S.SP_VALUE_DATE,
I.STATUS_FLAG, I.STATUS_LAST_UPDATED
from PRODUCT
join (select SUBPRODUCT.*,
max(SP_VALUE_DATE) over (partition by SP_PRODUCT_ID) as latestDate
from SUBPRODUCT) S
on PRODUCT.P_ID = S.SP_PRODUCT_ID
and S.SP_VALUE_DATE = S.latestDate
join (select ISSUES.*,
max(STATUS_LAST_UPDATED) over (partition by ISSUE_ID) as latestDate
from ISSUES) I
on I.ISSUE_ID = S.SP_ID
and I.STATUS_LAST_UPDATED = I.latestDate
这通常会表现得更好一些,但是 window 函数可能很难理解。
使用 Oracle SQL Developer,我有三个 table 需要加入一些常用数据。
感谢对此的任何帮助!
请参阅 https://i.stack.imgur.com/f37Jh.png 了解输入和所需的输出(table 格式不适用于所有 table)。 这些 table 是为了匿名化而编造的,实际上包含具有数百万条目的其他数据,但您可以将它们视为代表:
- 产品 = 杂货店的主要产品类别。
- Subproduct = 上述产品的子类别。每次 table 更新时,主要产品类别可能会丢失或获得一些分配给它的新产品。例如。你可以看到从五月到六月,拉肉进来了,鱼汤被扔掉了。
- 问题 = 产品状态,例如,如果苹果上有褐色斑点,则表明它是坏的..
我需要找的是:对每个P_NAME,找到最新更新的一组子产品(SP_ID和SP_NAME ),并将该信息附加到最新更新的问题状态 (STATUS_FLAG)。
请注意,每个主要产品类别都会在不同的场合更新其子产品集,即 1234 和 5678 可能在不同的日期“最新更新”。
我尝试了多次查询,但每次都失败了。我正在使用 SELECT
、LEFT OUTER JOIN
、JOIN
、MAX
和 GROUP BY
.
最新尝试,它给出了前两个 table 的组合,但缺少第三个:
SELECT
PRODUCT.P_NAME,
SUBPRODUCT.SP_PRODUCT_ID, SUBPRODUCT.SP_NAME, SUBPRODUCT.SP_ID, SUPPRODUCT.SP_VALUE_DATE
FROM SUBPRODUCT
LEFT OUTER JOIN PRODUCT ON PRODUCT.P_ID = SUBPRODUCT.SP_PRODUCT_ID
JOIN(SELECT SP_PRODUCT_ID, MAX(SP_VALUE_DATE) AS latestdate FROM SUBPRODUCT GROUP BY SP_PRODUCT_ID) sub ON
sub.SP_PRODUCT_ID = SUBPRODUCT.SP_PRODUCT_ID AND sub.latestDate = SUBPRODUCT.SP_VALUE_DATE;
尝试查找具有最大值的行是一种常见的 SQL 模式 - 您可以使用连接来完成,就像您的示例一样,但通常使用子查询或 window函数。
相关子查询示例
select
PRODUCT.P_NAME,
SUBPRODUCT.SP_PRODUCT_ID, SUBPRODUCT.SP_NAME, SUBPRODUCT.SP_ID, SUPPRODUCT.SP_VALUE_DATE,
ISSUES.STATUS_FLAG, ISSUES.STATUS_LAST_UPDATED
from PRODUCT
join SUBPRODUCT
on PRODUCT.P_ID = SUBPRODUCT.SP_PRODUCT_ID
and SUBPRODUCT.SP_VALUE_DATE = (select max(S2.SP_VALUE_DATE) as latestDate
from SUBPRODUCT S2
where S2.SP_PRODUCT_ID = SUBPRODUCT.SP_PRODUCT_ID)
join ISSUES
on ISSUES.ISSUE_ID = SUBPRODUCT.SP_ID
and ISSUES.STATUS_LAST_UPDATED = (select max(I2.STATUS_LAST_UPDATED) as latestDate
from ISSUES I2
where I2.ISSUE_ID = ISSUES.ISSUE_ID)
Window 函数/内联视图示例
select
PRODUCT.P_NAME,
S.SP_PRODUCT_ID, S.SP_NAME, S.SP_ID, S.SP_VALUE_DATE,
I.STATUS_FLAG, I.STATUS_LAST_UPDATED
from PRODUCT
join (select SUBPRODUCT.*,
max(SP_VALUE_DATE) over (partition by SP_PRODUCT_ID) as latestDate
from SUBPRODUCT) S
on PRODUCT.P_ID = S.SP_PRODUCT_ID
and S.SP_VALUE_DATE = S.latestDate
join (select ISSUES.*,
max(STATUS_LAST_UPDATED) over (partition by ISSUE_ID) as latestDate
from ISSUES) I
on I.ISSUE_ID = S.SP_ID
and I.STATUS_LAST_UPDATED = I.latestDate
这通常会表现得更好一些,但是 window 函数可能很难理解。