2016-05-30 104 views
0

我有我猜测的是一个常见的数据仓库问题。SQL填写缺少日期

我一直在试图做的是做一个SQL日期之间没有差距的查询。

事实表只记录被测量并记录到表中的记录。这个案例涉及海上船只的注册石油生产。有些日子有些船上没有生产。

所以这里是我的简单数据仓库:DimVessel,DimDateFactProduction。在下面你看到我想要的最终结果集。

我希望SQL Query能够用vesselkeyProduction填充事实表,即使船上没有生产。请记住,有些日子可能会在少数船舶上生产,其他日子可能会生产所有船舶(最好的情况)。

我希望有人能帮助我。

DimVessel

VesselKey| VesselName 
1  | Vessel 1 
2  | Vessel 2 
3  | Vessel 3 
4  | Vessel 4 
5  | Vessel 5 

DimDate

DateKey  |Date 
20160517 |2016-05-17 00:00:00.000 
20160518 |2016-05-18 00:00:00.000 
20160519 |2016-05-19 00:00:00.000 
20160520 |2016-05-20 00:00:00.000 

FactProduction

DateKey  |VesselKey |Production 
20160517 |4   |12505 
20160517 |5   |1276 
20160517 |3   |88 
20160517 |2   |3919 
20160518 |4   |8785 
20160518 |5   |736 
20160518 |1   |3754 
20160518 |2   |5654 
20160519 |2   |1654 
20160520 |1   |2016 
20160520 |3   |6059 
20160520 |4   |10980 
20160520 |5   |663 

这是我はnt,最终结果集:

DateKey  |VesselKey |Production 
20160517 |4   |12505 
20160517 |5   |1276 
20160517 |3   |88 
20160517 |2   |3919 
20160517 |1   |0 
20160518 |4   |8785 
20160518 |5   |736 
20160518 |3   |0 
20160518 |1   |3754 
20160518 |2   |5654 
20160519 |2   |1654 
20160519 |1   |0 
20160519 |3   |0 
20160519 |4   |0 
20160519 |5   |0 
20160520 |1   |2016 
20160520 |3   |6059 
20160520 |2   |4059 
20160520 |4   |10980 
20160520 |5   |663 
+0

有人会帮你确定。如果您将问题的格式设置为人类可读,如果您向我们展示了迄今为止所做的工作,并且告诉我们您的问题到底是什么 –

+0

您是否熟悉左连接? –

+0

我对你的问题的语法做了一些修改;如果他们以任何方式改变了含义,请随时回滚我的编辑。 –

回答

0

为什么要存储不存在的数据?我不喜欢存储实际上不存在于源系统中的事实数据。

你可以达到你想要用下面的查询(未测试)

SELECT DD.DateKey 
,DV.VesselKey 
,Production = ISNULL(FP.Production) 
FROM DimDate DD 
    INNER JOIN DimVessel DV ON 1 = 1 
    LEFT JOIN FactProduction FP ON (FP.DateKey = DD.DateKey AND FP.VesselKey = DV.VesselKey) 
WHERE DD.DateKey BETWEEN @StartDate AND @EndDate 

如果你坚持想保存数据,那么你只需要添加一个连接到您的源数据,而不是结果FactProduction表,然后将结果插入到你的事实

+0

关于不存在的数据,你是指dimDate表吗? –

+0

不太确定我说的是事实数据。 DimDate是一个维度。如果我们想进入语义学,那么DimDate就来自日历(Pseudo)。国际海事组织从事实数据表中缺失的记录比创建填补空白的记录更具信息量。可能表示源数据问题或只是突出显示数据尚未完成/尚未完成 – DamutuMike

+0

嗨,感谢所有评论。有时候像这里生产停止时一样,没有数据被注册。在时间线0生产也是数据,即使它没有以任何方式测量。当以图表或图表形式呈现时,您的数据中会出现漏洞。可能是可以理解的,但也可能会被误解。 – user5767413

0

这里是一个有效的解决方案:

select allCombinations.DateKey, 
     allCombinations.VesselKey, 
     isnull(p.Production, 0) as Production 
from (
     select d.DateKey, 
       v.VesselKey 
     from @Dates as d 
     cross join @Vessels as v 
     ) as allCombinations 
left join @Production as p 
on  allCombinations.DateKey = p.DateKey 
     and allCombinations.VesselKey = p.VesselKey 

为了验证该解决方案的完整的代码是后续ing:

declare @Vessels table 
    (
    VesselKey int primary key 
        not null, 
    VesselName as (N'Vessel ' + cast(VesselKey as nvarchar)) 
    ) 

insert into @Vessels 
     (VesselKey) 
values (1), 
     (2), 
     (3), 
     (4), 
     (5) 

select * 
from @Vessels as v 

declare @Dates table 
    (
    DateKey int primary key 
       not null, 
    Date as (try_convert(datetime2, cast(DateKey as nvarchar) 
       + ' 00:00:00.000')) 
    ) 

insert into @Dates 
     (DateKey) 
values (20160517), 
     (20160518), 
     (20160519), 
     (20160520) 

select * 
from @Dates as d 

declare @Production table 
    (
    DateKey int, 
    VesselKey int, 
    Production int 
    ) 

insert into @Production 
     (DateKey, VesselKey, Production) 
values (20160517, 4, 12505), 
     (20160517, 5, 1276), 
     (20160517, 3, 88), 
     (20160517, 2, 3919), 
     (20160518, 4, 8785), 
     (20160518, 5, 736), 
     (20160518, 1, 3754), 
     (20160518, 2, 5654), 
     (20160519, 2, 1654), 
     (20160520, 1, 2016), 
     (20160520, 3, 6059), 
     (20160520, 4, 10980), 
     (20160520, 5, 663) 

select * 
from @Production as p 



select allCombinations.DateKey, 
     allCombinations.VesselKey, 
     isnull(p.Production, 0) as Production 
from (
     select d.DateKey, 
       v.VesselKey 
     from @Dates as d 
     cross join @Vessels as v 
     ) as allCombinations 
left join @Production as p 
on  allCombinations.DateKey = p.DateKey 
     and allCombinations.VesselKey = p.VesselKey 

让我知道如果结果不是你要找的那个。

+0

是的,谢谢。我猜想在第二个查询中,我希望按小时更详细的数据,我可以使用此查询仅添加DimTime中的TimeKey(0-1439),并在白天每分钟注册一个生产样本。第二个查询将显示过去24小时的滑动窗口,如昨天上午10点16分至今天上午10点15分,以及5分钟后上午10点21分至今天上午10点20分。我也会尝试在我的新案例中使用这个查询。并再次感谢非常快速的响应。问候盖尔 – user5767413