1

信息


我需要一些帮助来找出查询一组表的最佳方法。需要从两个相互关联的表中找到数据可用的最小和最大月份。有问题的表格和列如下所述:

股票

stock_id | region_id

地区

region_id | region_name

股票回报

stock_id | month | return

区域回报

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
4

1 回答 1

0

您可以消除与 Regions 表的连接,因为只有在需要区域名称时才连接到该表。由于您只是检查股票区域是否存在两种返回类型,因此您也可以使用存在子句。

试试这个怎么样?

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
于 2013-10-26T05:38:17.177 回答