优化 - 在这种情况下联合是最好的方法吗?
Optimization - is union the best way to go in this case?
我有一个每天从外部数据源更新的数据集(示例)。然后将此数据与其他一些内部数据(Scale)组合并形成一个新的 table。
示例包含一些有时可能出错的数字。我在单独的 table(错误)中注册了数据不正确的资金和日期。我希望从我知道正确的另一个日期获取数据并将其用作代理。
我做了一小段代码来说明我的问题。所以 - 目的是最终得到一个完整的 table,其中包含不同公司投资组合中所有单一投资(即,我查看投资基金)的历史数据。如果基金的任何数据在交付时出现错误,则该基金的数据应取自另一日期(不一定是之前的日期)。即使不正确的数据被另一个日期的数据替换,缩放比例也应保持不变。
我深思熟虑后发现,我似乎找到解决方案的唯一方法是对两个不同的选择进行 UNION,一个是原始数据(不包括具有不正确数据的资金),另一个是替换数据。但我觉得应该有一种更简单的方法来实现我所需要的。我的原始数据既存在于表格中,也存在于视图中,而且很大而且有点慢,就像现在一样,所以我有兴趣找到最有效的方法来创建新的 table.
提前致谢!
行
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 data.MarketDate=@Todate
and data.FundName not in (select FundName from Errors where MarketDate=@Todate)
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 marketdate=@todate)
and marketdate in (select riskdate from Errors where marketdate=@todate)
) data
inner join tblScale scale
on data.FundName=scale.FundName
and data.Today=scale.MarketDate
where scale.MarketDate=@Todate
group by data.MarketDate
,scale.Entity
,data.SecurityName
,scale.Scale
,scale.MarketDate
首先,您可以使用 UNION ALL
,这样可以省去重复检查。这会快得多。
另一个建议是第一个 SELECT
中的 IN()
。如果您的子查询 returns 多行,这可能会导致运行时间过长。
我建议重新设计它:
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 data.MarketDate=@Todate
and data.FundName not in (select FundName from Errors where MarketDate=@Todate)
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 MarketDate=@Todate) as fundname
ON data.FundName = fundname.FundName
where data.MarketDate=@Todate
and fundname.Fundname IS NULL
group by data.MarketDate,scale.Entity,data.SecurityName,scale.Scale
我有一个每天从外部数据源更新的数据集(示例)。然后将此数据与其他一些内部数据(Scale)组合并形成一个新的 table。
示例包含一些有时可能出错的数字。我在单独的 table(错误)中注册了数据不正确的资金和日期。我希望从我知道正确的另一个日期获取数据并将其用作代理。
我做了一小段代码来说明我的问题。所以 - 目的是最终得到一个完整的 table,其中包含不同公司投资组合中所有单一投资(即,我查看投资基金)的历史数据。如果基金的任何数据在交付时出现错误,则该基金的数据应取自另一日期(不一定是之前的日期)。即使不正确的数据被另一个日期的数据替换,缩放比例也应保持不变。
我深思熟虑后发现,我似乎找到解决方案的唯一方法是对两个不同的选择进行 UNION,一个是原始数据(不包括具有不正确数据的资金),另一个是替换数据。但我觉得应该有一种更简单的方法来实现我所需要的。我的原始数据既存在于表格中,也存在于视图中,而且很大而且有点慢,就像现在一样,所以我有兴趣找到最有效的方法来创建新的 table.
提前致谢! 行
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 data.MarketDate=@Todate
and data.FundName not in (select FundName from Errors where MarketDate=@Todate)
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 marketdate=@todate)
and marketdate in (select riskdate from Errors where marketdate=@todate)
) data
inner join tblScale scale
on data.FundName=scale.FundName
and data.Today=scale.MarketDate
where scale.MarketDate=@Todate
group by data.MarketDate
,scale.Entity
,data.SecurityName
,scale.Scale
,scale.MarketDate
首先,您可以使用 UNION ALL
,这样可以省去重复检查。这会快得多。
另一个建议是第一个 SELECT
中的 IN()
。如果您的子查询 returns 多行,这可能会导致运行时间过长。
我建议重新设计它:
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 data.MarketDate=@Todate
and data.FundName not in (select FundName from Errors where MarketDate=@Todate)
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 MarketDate=@Todate) as fundname
ON data.FundName = fundname.FundName
where data.MarketDate=@Todate
and fundname.Fundname IS NULL
group by data.MarketDate,scale.Entity,data.SecurityName,scale.Scale