2015-06-20 34 views
0

我有一个每天从外部数据源更新的数据集(示例)。然后将这些数据与一些其他内部数据(比例)组合在一起,并形成一个新表格。优化 - 在这种情况下,工会是最好的方式吗?

示例包含一些有时可能有误的数字。我在单独的表格中注册了哪些资金和日期数据不正确(错误)。我希望从另一个我知道是正确的日期获取数据,并将其用作代理。

我已经做了一小段代码来说明我的问题。所以 - 最终的目的是最终建立一个完整的表格,其中包含所有单项投资的历史数据(也就是我查看投资基金)在不同公司的投资组合中的历史数据。如果某个基金的任何数据发生了错误,基金的数据应该从另一个日期(不一定是前一日期)中提取。即使不正确的数据被来自其他日期的数据替代,缩放比例也应该保持不变。

我给了它很多的想法,发现唯一的办法,我似乎找出解决办法是UNION两个不同的选择,其中一个与原始数据不包括资金不正确的数据和一个替换数据。但我觉得应该有一个更简单的方法来实现我所需要的。我的原始数据都是表格和视图,而且它们现在很庞大而且有点慢,所以我很想找到创建新表的最有效方法。

在此先感谢! 线

CREATE TABLE Example(
    MarketDate datetime NOT NULL, 
    FundName VARCHAR(20) NOT NULL, 
    SecurityName VARCHAR(48) NOT NULL, 
    MarketValue FLOAT(25), 
    Risk FLOAT(25), 
); 

CREATE TABLE tblScale(
    MarketDate datetime NOT NULL, 
    Entity VARCHAR (20) NOT NULL, 
    FundName VARCHAR(48) NOT NULL, 
    Scale FLOAT(25), 
); 

CREATE TABLE Errors(
    MarketDate datetime NOT NULL, 
    RiskDate datetime NOT NULL, 
    FundName VARCHAR(48) NOT NULL, 
); 


INSERT INTO Example (MarketDate,FundName,SecurityName,MarketValue,Risk) VALUES ('2015-06-15', 'Fund1', 'Bond1', 2000.00, 5); 
INSERT INTO Example (MarketDate,FundName,SecurityName,MarketValue,Risk) VALUES ('2015-06-15', 'Fund1', 'Bond2', 1500.00, 4); 
INSERT INTO Example (MarketDate,FundName,SecurityName,MarketValue,Risk) VALUES ('2015-06-15', 'Fund1', 'Bond3', 1300.00, 3); 
INSERT INTO Example (MarketDate,FundName,SecurityName,MarketValue,Risk) VALUES ('2015-06-15', 'Fund1', 'Bond4', 300.00, 109); 
INSERT INTO Example (MarketDate,FundName,SecurityName,MarketValue,Risk) VALUES ('2015-06-15', 'Fund1', 'Bond5', 700.00, 400); 
INSERT INTO Example (MarketDate,FundName,SecurityName,MarketValue,Risk) VALUES ('2015-06-15', 'Fund1', 'Bond6', 600.00, 350); 
INSERT INTO Example (MarketDate,FundName,SecurityName,MarketValue,Risk) VALUES ('2015-06-14', 'Fund1', 'Bond1', 2100.00, 5.1); 
INSERT INTO Example (MarketDate,FundName,SecurityName,MarketValue,Risk) VALUES ('2015-06-14', 'Fund1', 'Bond2', 1400.00, 4.2); 
INSERT INTO Example (MarketDate,FundName,SecurityName,MarketValue,Risk) VALUES ('2015-06-14', 'Fund1', 'Bond3', 1330.00, 3.9); 
INSERT INTO Example (MarketDate,FundName,SecurityName,MarketValue,Risk) VALUES ('2015-06-14', 'Fund1', 'Bond4', 200.00, 2.1); 
INSERT INTO Example (MarketDate,FundName,SecurityName,MarketValue,Risk) VALUES ('2015-06-14', 'Fund1', 'Bond5', 400.00, 2.5); 
INSERT INTO Example (MarketDate,FundName,SecurityName,MarketValue,Risk) VALUES ('2015-06-14', 'Fund1', 'Bond6', 500.00, 2.6); 
INSERT INTO Example (MarketDate,FundName,SecurityName,MarketValue,Risk) VALUES ('2015-06-15', 'Fund2', 'Bond7', 1800.00, 3.5); 
INSERT INTO Example (MarketDate,FundName,SecurityName,MarketValue,Risk) VALUES ('2015-06-15', 'Fund2', 'Bond8', 1900.00, 4.5); 
INSERT INTO Example (MarketDate,FundName,SecurityName,MarketValue,Risk) VALUES ('2015-06-15', 'Fund2', 'Bond9', 1300.00, 3); 
INSERT INTO Example (MarketDate,FundName,SecurityName,MarketValue,Risk) VALUES ('2015-06-15', 'Fund2', 'Bond10', 350.00, 2.1); 
INSERT INTO Example (MarketDate,FundName,SecurityName,MarketValue,Risk) VALUES ('2015-06-14', 'Fund2', 'Bond7', 1700.00, 3.4); 
INSERT INTO Example (MarketDate,FundName,SecurityName,MarketValue,Risk) VALUES ('2015-06-14', 'Fund2', 'Bond8', 1810.00, 4.2); 
INSERT INTO Example (MarketDate,FundName,SecurityName,MarketValue,Risk) VALUES ('2015-06-14', 'Fund2', 'Bond9', 1330.00, 3.4); 
INSERT INTO Example (MarketDate,FundName,SecurityName,MarketValue,Risk) VALUES ('2015-06-14', 'Fund2', 'Bond10', 320.00, 2.0); 

INSERT INTO tblScale (MarketDate,Entity,FundName,Scale) VALUES ('2015-06-15', 'Comp1', 'Fund1', 0.76); 
INSERT INTO tblScale (MarketDate,Entity,FundName,Scale) VALUES ('2015-06-15', 'Comp2', 'Fund1', 0.10); 
INSERT INTO tblScale (MarketDate,Entity,FundName,Scale) VALUES ('2015-06-15', 'Comp3', 'Fund1', 0.14); 
INSERT INTO tblScale (MarketDate,Entity,FundName,Scale) VALUES ('2015-06-15', 'Comp1', 'Fund2', 0.30); 
INSERT INTO tblScale (MarketDate,Entity,FundName,Scale) VALUES ('2015-06-15', 'Comp2', 'Fund2', 0.35); 
INSERT INTO tblScale (MarketDate,Entity,FundName,Scale) VALUES ('2015-06-15', 'Comp3', 'Fund2', 0.25); 
INSERT INTO tblScale (MarketDate,Entity,FundName,Scale) VALUES ('2015-06-14', 'Comp1', 'Fund1', 0.75); 
INSERT INTO tblScale (MarketDate,Entity,FundName,Scale) VALUES ('2015-06-14', 'Comp2', 'Fund1', 0.10); 
INSERT INTO tblScale (MarketDate,Entity,FundName,Scale) VALUES ('2015-06-14', 'Comp3', 'Fund1', 0.15); 
INSERT INTO tblScale (MarketDate,Entity,FundName,Scale) VALUES ('2015-06-14', 'Comp1', 'Fund2', 0.30); 
INSERT INTO tblScale (MarketDate,Entity,FundName,Scale) VALUES ('2015-06-14', 'Comp2', 'Fund2', 0.35); 
INSERT INTO tblScale (MarketDate,Entity,FundName,Scale) VALUES ('2015-06-14', 'Comp3', 'Fund2', 0.25); 

INSERT INTO Errors (MarketDate,RiskDate,FundName) VALUES ('2015-06-15', '2015-06-14', 'Fund1'); 

Declare @Todate as datetime = '2015-06-15'; 

select data.MarketDate as MarketDate 
     ,data.MarketDate as RiskDate 
     ,scale.Entity 
     ,data.SecurityName 
     ,sum(data.MarketValue)*scale.Scale as MV 
from Example data 
inner join tblScale scale 
on data.MarketDate=scale.MarketDate 
and data.FundName=scale.FundName 
where [email protected] 
and data.FundName not in (select FundName from Errors where [email protected]) 
group by data.MarketDate,scale.Entity,data.SecurityName,scale.Scale 

union 

select @Todate as MarketDate 
     ,data.MarketDate as RiskDate 
     ,scale.Entity 
     ,data.SecurityName 
     ,sum(data.MarketValue)*scale.Scale as MV 
from (select @Todate as Today,* from Example 
     where fundname in (select fundname from Errors where [email protected]) 
     and marketdate in (select riskdate from Errors where [email protected]) 
    ) data 
inner join tblScale scale 
on data.FundName=scale.FundName 
and data.Today=scale.MarketDate 
where [email protected] 
group by data.MarketDate 
     ,scale.Entity 
     ,data.SecurityName 
     ,scale.Scale 
     ,scale.MarketDate 
+1

如果您不需要移除可能从未来可重复的行不同的选择,使用“联盟全部”而不是 –

+0

是的你的权利@JamesZ。当他使用'@ todate'变量来排除第一个语句中的行时,它们将不会重复。 – Ionic

+0

请编辑您的帖子,以包含各种表格的索引和此查询的解释计划 – TheMadDBA

回答

0

那么首先,你可以使用UNION ALL,这将省去重复检查。这会更快。

另一个建议是您的第一个SELECT中的IN()。如果你的子查询返回多行,这可能会导致很长的运行时间。

我建议从这个重新设计:

select data.MarketDate as MarketDate 
     ,data.MarketDate as RiskDate 
     ,scale.Entity 
     ,data.SecurityName 
     ,sum(data.MarketValue)*scale.Scale as MV 
from Example data 
INNER join tblScale scale 
on data.MarketDate=scale.MarketDate 
and data.FundName=scale.FundName 
where [email protected] 
and data.FundName not in (select FundName from Errors where [email protected]) 
group by data.MarketDate,scale.Entity,data.SecurityName,scale.Scale 

对此LEFT JOIN包括IS NULL筛选:

select data.MarketDate as MarketDate 
     ,data.MarketDate as RiskDate 
     ,scale.Entity 
     ,data.SecurityName 
     ,sum(data.MarketValue)*scale.Scale as MV 
from Example data 
inner join tblScale scale 
on data.MarketDate=scale.MarketDate 
and data.FundName=scale.FundName 
LEFT JOIN (select FundName from Errors where [email protected]) as fundname 
     ON data.FundName = fundname.FundName 
where [email protected] 
and fundname.Fundname IS NULL 
group by data.MarketDate,scale.Entity,data.SecurityName,scale.Scale 
+0

感谢您的建议,但我很抱歉地说我并不真正了解他们......您加入了出现在错误中的FundNames,但我想在我的第一个选择中排除那些FundNames,因为这些是在@Todate的例子中有错误的数据。加入“fundname.FundName IS NULL”后面的想法是什么?因为在Error表中永远不会有NULL的注册。 – Line

+0

忘了提及,当我运行上面的建议选择时,它返回空。 – Line

+0

对不起,我现在没有多少时间。但要提一下,我在第二次选择时出错了。我现在纠正了它。你可以再试一次。 – Ionic

相关问题