我需要一些帮助来找出查询一组表的最佳方法。需要找到两个互连表中可获得数据的最小和最大月份。有问题的表格和列如下所述:
股票
stock_id | region_id
地区
region_id | region_name
StockReturns
stock_id | month | return
RegionReturns
region_id | return_type_id | month | return
返回类型
return_type_id | return_type_name
我已在SQL Fiddle
为此创建了一个沙箱我想回答的问题是:对于给定的开始和结束月份(190001,201310),股票(VTI)及其相应区域的最早和最新回报数据是什么( 1)?此数据将用于根据日期范围进一步查询具有正确开始和结束月份的其他表。
我当前的查询(如下所述)开始在执行时间方面逐渐增加,因为这是在大多数网页加载时运行的主要查询,我关注性能。
关于数据,架构不是一成不变的,如果更适合这些类型的查询,可以更改架构。此外,ReturnType的构建方式与EAV类似,但它具有有限的选项限制(生产表中为5)。 StockReturns表目前有超过100,000行,并且上限为200万条记录。 RegionReturns表有3000行,上限为5000.
目前我正在查询类似的内容:
SELECT s.stock_id
,MIN(sr.month) AS start_month
,MAX(sr.month) AS end_month
FROM StockReturns sr
INNER JOIN Stocks s ON sr.stock_id = s.stock_id AND s.stock_id = 'VTI'
INNER JOIN Regions r ON s.region_id = r.region_id
INNER JOIN RegionReturns rf ON s.region_id = rf.region_id
AND rf.return_type_id = 1
AND sr.month = rf.month
INNER JOIN RegionReturns mkt ON s.region_id = mkt.region_id
AND mkt.return_type_id = 2
AND sr.month = mkt.month
WHERE sr.month BETWEEN 190001 AND 201310
GROUP BY s.stock_id
本案的答案应该是:
stock_id | start_month | end_month
--------- ------------- ----------
VTI | 201301 | 201302
答案 0 :(得分:0)
您可以使用Regions表取消连接,因为如果需要区域名称,则只能加入该表。由于您只是检查股票区域是否存在两种返回类型,因此您也可以使用exists子句。
尝试这个怎么样?
SELECT sr.stock_id,
MIN(sr.month) AS start_month,
MAX(sr.month) AS end_month
FROM StockReturns sr,
Stocks s
WHERE sr.stock_id = s.stock_id
AND s.stock_id = 'VTI'
AND sr.month BETWEEN 190001 AND 201310
AND EXISTS (SELECT 1
FROM RegionReturns rr
WHERE rr.region_id = s.region_id
AND rr.return_type_id = 1
AND rr.month = sr.month)
AND EXISTS (SELECT 1
FROM RegionReturns rr
WHERE rr.region_id = s.region_id
AND rr.return_type_id = 2
AND rr.month = sr.month)
GROUP BY sr.stock_id