我有一个带有表结构的Forecast和Actuals表:
YearNb, WeekNb, Country, Product, Volume
现在,我正在处理具有将两者结合在一起的相同结构的第三个表。 我已经有一个查询,该查询只是导入所有实际值。现在,我需要导入所有相关的预测。这导致了我的问题。我只需要日期比实际日期更近的预测。 “预测”表包括所有历史预测,其中大多数都不相关。我需要在国家/地区级别进行此检查,因为我们在国家/地区级别上收到此数据,并且不同国家/地区的近期实际情况可能有所不同。
我已经做了:
WITH cte AS
(
SELECT Country, YearNb, WeekNb, (YearNb*100 + WeekNb) AS Date,
ROW_NUMBER() OVER (PARTITION BY Country ORDER BY (YearNb*100 + WeekNb) DESC) AS rn
FROM Actuals
)
SELECT *
FROM cte
WHERE rn = 1
这为我提供了每个国家的分组列表,其中包含最新的实际数据日期。 但是现在我有点卡住了如何使用它来从具有最近日期的预测表中选择数据。
Country YearNb WeekNb Date
A 2018 29 201829
B 2019 5 201905
C 2018 34 201834
重要的一点是,我需要在产品级别上使用此数据,以便与原始两个表具有相同的结构。 因此,作为最终输出,我需要日期201829之后的国家A的所有产品的所有预测,日期201905之后的国家B的所有数据,等等。
答案 0 :(得分:2)
尝试在field
年之前加入,并添加条件以获取更早的日期:
SELECT
*
FROM Actuals act
INNER JOIN
(
SELECT
(
SELECT
Country, YearNb, WeekNb, (YearNb*100 + WeekNb) AS Date,
ROW_NUMBER() OVER (PARTITION BY Country ORDER BY (YearNb*100 + WeekNb) DESC) AS rn
FROM Actuals
WHERE ROW_NUMBER() OVER (PARTITION BY Country ORDER BY (YearNb*100 + WeekNb) DESC) = 1
)
WHERE RN = 1
)q ON act.YearNb = q.YearNb and (act.YearNb*100 + act.WeekNb) < q.Date
答案 1 :(得分:2)
我将对NOT EXISTS
使用依赖查询
select YearNb, WeekNb, Country, Product, Volume
from Forecast f
where not exists (
select 1
from Actual a
where a.country = f.country and
a.YearNb * 100 + a.WeekNb >= f.YearNb * 100 + f.WeekNb
)
这将从您的Forecast
表中选择相关数据。如果考虑性能,那么EXISTS
属性上有一个索引,country
的性能会更好。
编辑
如果您想忽略forecats
个不在实际中的国家,请使用半联接
select f.*
from Forecast f
where not exists (
select 1
from Actual a
where a.country = f.country and
a.YearNb * 100 + a.WeekNb >= f.YearNb * 100 + f.WeekNb
) and
exists(
select 1
from Actual a
where a.country = f.country
)
答案 2 :(得分:1)
使用您自己的CTE,您可以得到
WITH cte AS
(
SELECT Country, YearNb, WeekNb, (YearNb*100 + WeekNb) AS Date,
ROW_NUMBER() OVER (PARTITION BY Country ORDER BY (YearNb*100 + WeekNb) DESC) AS rn
FROM Actuals
)
SELECT f.*
FROM forecast f
JOIN cte ON f.Country = cte.Country AND cte.date < (f.YearNb*100 + f.WeekNb)
WHERE cte.rn = 1
答案 3 :(得分:0)
我会使用cross apply
:
select f.*, a.*
from (select a.*,
row_number() over (partition by country order by yearnb desc, weeknb desc) as seqnum
from actuals a
) a cross apply
(select f.*
from forecast f
where f.country = a.country and
(f.yearnb > a.yearnb or
f.yearnb = a.yearnb and f.weeknb > a.weeknb
)
) f
where a.seqnum = 1;
这使得从两个表中选择列变得容易。