SQL Server:使用来自另一个表或视图的参数连接一个表中的平均数据

Posted

技术标签:

【中文标题】SQL Server:使用来自另一个表或视图的参数连接一个表中的平均数据【英文标题】:SQL Server: Joining Average Data from a table using parameters from another table or view 【发布时间】:2017-07-28 19:22:58 【问题描述】:

我有两个由以下内容定义的表:

CREATE TABLE Portfolio.DailyStats
(
     Date date NOT NULL,
     NAV int NOT NULL,
     SP500 decimal(8,4) NULL,
     R2K decimal(8,4) NULL,
     NetExp decimal(8,4) NULL,
     GrossExp decimal(8,4) NULL,
)
GO

CREATE TABLE Portfolio.DailyPortfolio
(
     BbgID varchar(30) NOT NULL,
     Ticker varchar(22) NULL,
     Cusip char(9) NULL,
     SecurityDescription varchar(50) NOT NULL,
     AssetCategory varchar(25) NOT NULL,
     LSPosition char(3) NULL,
     Ccy varchar(25) NOT NULL,
     Quantity int NULL,
     DeltaExpNet int NULL,
     Issuer varchar(48) NOT NULL,
     Date date NOT NULL,
     PortfolioID AS BbgID + LSPosition + Convert(varchar(8), Date, 112) Persisted Primary Key
)
GO

我正在尝试创建一个包含 4 列的视图,在该视图中我可以看到每个 Issuer,查看 Issuer 在 DailyPortfolio 表中第一个和最后一个出现的日期以及来自 DailyStats 表的平均 NAV那些日期。所以这个视图的前三列将定义为:

SELECT 
    Issuer, MIN(Date) OpenDate, MAX(Date) CloseDate
FROM 
    Portfolio.DailyPortfolio
GROUP BY 
    Issuer

如何使用DailyStats 表中的NAV 列为视图中MIN(Date)MAX(Date) 列定义的日期范围添加计算AverageNAV 的第四列。

我的最终视图应该是这样的:

Issuer  OpenDate    CloseDate   AverageNAV
:------|-----------|-----------|----------:
Issuer A  2/4/2015   11/9/2016  28234164
Issuer B  2/6/2015   5/19/2017  30446780
Issuer C  11/19/2015 10/11/2016 35789424

【问题讨论】:

【参考方案1】:

如果您使用 CTE 按发行人定义日期范围,则可以使用 AVG 获得每个日期范围的单个平均值:

;WITH DateRange AS(
SELECT DP.Issuer, MIN(DP.Date) OpenDate, MAX(DP.Date) CloseDate
FROM Portfolio.DailyPortfolio DP
GROUP BY DP.Issuer
)
SELECT DR.Issuer, DR.OpenDate, DR.CloseDate, AVG(DS.NAV) AS AverageNAV
FROM DateRange DR
INNER JOIN Portfolio.DailyStats DS ON DS.Date BETWEEN DR.OpenDate AND DR.CloseDate
GROUP BY DR.Issuer, DR.OpenDate, DR.CloseDate

这是带有示例数据和输出的完整示例代码:

DECLARE @DailyStats TABLE
(Date DATE NOT NULL,
NAV INT NOT NULL)

DECLARE @DailyPortfolio TABLE
(Issuer VARCHAR(48) NOT NULL,
Date DATE NOT NULL)

INSERT INTO @DailyPortfolio VALUES ('Max', '1/1/2017')
INSERT INTO @DailyPortfolio VALUES ('Max', '2/1/2017')
INSERT INTO @DailyPortfolio VALUES ('Max', '3/1/2017')
INSERT INTO @DailyPortfolio VALUES ('Max', '4/1/2017')
INSERT INTO @DailyPortfolio VALUES ('Scott', '1/1/2015')
INSERT INTO @DailyPortfolio VALUES ('Scott', '2/1/2017')
INSERT INTO @DailyPortfolio VALUES ('Scott', '3/1/2017')
INSERT INTO @DailyPortfolio VALUES ('Scott', '4/1/2017')

INSERT INTO @DailyStats VALUES ('1/1/2016', 100)
INSERT INTO @DailyStats VALUES ('2/1/2017', 200)
INSERT INTO @DailyStats VALUES ('3/1/2017', 300)
INSERT INTO @DailyStats VALUES ('3/3/2017', 400)

;WITH DateRange AS(
SELECT DP.Issuer, MIN(DP.Date) OpenDate, MAX(DP.Date) CloseDate
FROM @DailyPortfolio DP
GROUP BY DP.Issuer
)
SELECT DR.Issuer, DR.OpenDate, DR.CloseDate, AVG(DS.NAV) AS AverageNAV
FROM DateRange DR
INNER JOIN @DailyStats DS ON DS.Date BETWEEN DR.OpenDate AND DR.CloseDate
GROUP BY DR.Issuer, DR.OpenDate, DR.CloseDate

输出:

Issuer   OpenDate    CloseDate    AverageNAV
Max      2017-01-01  2017-04-01   300
Scott    2015-01-01  2017-04-01   250

【讨论】:

效果很好。谢谢!

以上是关于SQL Server:使用来自另一个表或视图的参数连接一个表中的平均数据的主要内容,如果未能解决你的问题,请参考以下文章

是否有列出 SQL Server 中所有内置函数的系统表或系统视图?

SQL server设置用户只能访问特定数据库访问特定表或视图

SQL Server和Oracle数据库索引介绍

SQL 错误:ORA-00942 表或视图不存在

表或视图不存在

SQL Server根据表或视图批量生成插入语句并BCP导出成文本