让我们假设您有一个价值组合,其中包含需要定价的4个资产。 SourceID规定了应该给出PriceSource的优先级,并且应该检索最低的SourceID。如果EODPrice表中没有可用的价格,则应检索AverageBookCost(它位于不同的表中)。我正在使用SQL Server 2005。
举个例子,假设EODPrice表有以下数据('TEST004'缺失):
SourceID Date Ticker Price
0 2011-08-02 00:00:00 TEST001 104.50
1 2011-08-01 00:00:00 TEST001 100.00
1 2011-08-02 00:00:00 TEST001 105.00
1 2011-08-04 00:00:00 TEST001 115.00
2 2011-08-03 00:00:00 TEST001 109.38
2 2011-08-04 00:00:00 TEST001 114.24
1 2011-08-01 00:00:00 TEST002 9.99
1 2011-08-02 00:00:00 TEST002 9.89
1 2011-08-03 00:00:00 TEST002 9.79
1 2011-08-04 00:00:00 TEST002 9.69
0 2011-08-03 00:00:00 TEST003 0.42
2 2011-08-01 00:00:00 TEST003 0.33
2 2011-08-02 00:00:00 TEST003 0.38
2 2011-08-03 00:00:00 TEST003 0.28
2 2011-08-04 00:00:00 TEST003 0.45
让我们想象一下,我们想构建一个Select语句,我们为以下资产检索EODPrice('TEST001','TEST002','TEST003','TEST004')。请注意,'TEST004'是刚刚进入市场的新资产,在EODPrice表或市场中尚无价格。
此外,让我们假设任何日期的所有代码都有一个来自RunningTotal表的非NULL AverageBookCost字段。 (即SELECT AverageBookCost FROM RunningTotal WHERE Ticker ='TEST004'AND Date ='2011-08-03'将返回值0.15说。)
如何构建最有效的“相关”或“COALESCE / ISNULL”查询:
SELECT Ticker, SourceID, Price
???
WHERE [Date] = '2011-08-03'
AND [Ticker] IN ('TEST001','TEST002', 'TEST003' and 'TEST004')
这将返回下面的表:(注意'TEST004'Price是AverageBookCost而不在EODPrice表中,然后SourceID设置为NULL以指示Price来自RunningTotal表:
Ticker SourceID Price
TEST1 2 109.38
TEST2 1 9.79
TEST3 0 0.42
TEST4 NULL 0.15
非常感谢, 贝尔蒂。
答案 0 :(得分:2)
我很可能过于复杂,但这可能会让你开始。
简而言之,推理就像这样
SELECT
给定日期的所有代码及其最低的SourceID。JOIN
此子选择的结果返回原始表格。此步骤允许为具有给定日期和最低SourceID的每个股票代码检索价格。FULL OUTER JOIN
以前的结果与平均图书费用。此步骤会为每个行添加该股票代码的平均价格,并为没有从Pricetable返回的记录的代码添加行。SELECT
从这些结果中得出Price(如果可用),否则从附加列中选择平均图书费用。SELECT [Ticker] = ISNULL(pt.Ticker, pt_avg.Ticker)
, [SourceID] = pt.SourceID
, [Price] = ISNULL(pt.Price, pt_avg.AverageBookCost)
FROM EODPriceTable pt
INNER JOIN (
SELECT SourceID = MIN(SourceID), Ticker, Date
FROM EODPriceTable
WHERE Date = '2011-08-03 00:00:00'
GROUP BY
Ticker, Date
) pt_min ON pt_min.SourceID = pt.SourceID
AND pt_min.Ticker = pt.Ticker
AND pt_min.Date = pt.Date
FULL OUTER JOIN (
SELECT Ticker, AverageBookCost
FROM RunningTable
) pt_avg ON pt_avg.Ticker = pt.Ticker
WHERE ISNULL(pt.Ticker, pt_avg.Ticker) IN ('TEST001', 'TEST002', 'TEST003', 'TEST004')
;WITH EODPriceTable (SourceID, Date, Ticker, Price) AS (
SELECT 0, '2011-08-02 00:00:00', 'TEST001', 104.50
UNION ALL SELECT 1, '2011-08-01 00:00:00', 'TEST001', 100.00
UNION ALL SELECT 1, '2011-08-02 00:00:00', 'TEST001', 105.00
UNION ALL SELECT 1, '2011-08-04 00:00:00', 'TEST001', 115.00
UNION ALL SELECT 2, '2011-08-03 00:00:00', 'TEST001', 109.38
UNION ALL SELECT 2, '2011-08-04 00:00:00', 'TEST001', 114.24
UNION ALL SELECT 1, '2011-08-01 00:00:00', 'TEST002', 9.99
UNION ALL SELECT 1, '2011-08-02 00:00:00', 'TEST002', 9.89
UNION ALL SELECT 1, '2011-08-03 00:00:00', 'TEST002', 9.79
UNION ALL SELECT 1, '2011-08-04 00:00:00', 'TEST002', 9.69
UNION ALL SELECT 0, '2011-08-03 00:00:00', 'TEST003', 0.42
UNION ALL SELECT 2, '2011-08-01 00:00:00', 'TEST003', 0.33
UNION ALL SELECT 2, '2011-08-02 00:00:00', 'TEST003', 0.38
UNION ALL SELECT 2, '2011-08-03 00:00:00', 'TEST003', 0.28
UNION ALL SELECT 2, '2011-08-04 00:00:00', 'TEST003', 0.45
)
, RunningTable (Ticker, AverageBookCost) AS (
SELECT 'TEST004', 0.15
UNION ALL SELECT 'TEST003', 0.09
)
SELECT [Ticker] = ISNULL(pt.Ticker, pt_avg.Ticker)
, [SourceID] = pt.SourceID
, [Price] = ISNULL(pt.Price, pt_avg.AverageBookCost)
FROM EODPriceTable pt
INNER JOIN (
SELECT SourceID = MIN(SourceID), Ticker, Date
FROM EODPriceTable
WHERE Date = '2011-08-03 00:00:00'
GROUP BY
Ticker, Date
) pt_min ON pt_min.SourceID = pt.SourceID
AND pt_min.Ticker = pt.Ticker
AND pt_min.Date = pt.Date
FULL OUTER JOIN (
SELECT Ticker, AverageBookCost
FROM RunningTable
) pt_avg ON pt_avg.Ticker = pt.Ticker
WHERE ISNULL(pt.Ticker, pt_avg.Ticker) IN ('TEST001', 'TEST002', 'TEST003', 'TEST004')