繁体   English   中英

复杂(?)SQL连接查询

[英]Complex(?) SQL join query

我有2张桌子:

1)表Masterdates,包含自1900年1月1日以来的所有日期

2)表格Stockdata,其中包含日期,符号,开放,高,低,收盘,交易量(主键=日期,符号)形式的股票数据

这是我想要检索的内容(以CSV格式显示)

MDate,SDATE,符号,开盘价,最高价,...

6月4日/ 2001,6 / 4/2001年,美孚,47,49,...

6/5/2001年,NULL,NULL,NULL,NULL,...

6/6 / 2001,6 / 6/2001年,美孚,54,56,...

其中MDate来自Masterdates,而SDate来自Stockdata。 我需要让输出从Stockdata中所需符号的第一个(最早的)范围日期开始(在此示例中,Foo,从6/4/2001开始),然后包括Masterdates中的所有日期,包括最后一个日期(最新)Stockdata中所需符号的可用日期,输出空值,其中对于给定的Masterdate记录,在所描述的范围内没有相应的Stockdata记录。

有没有办法在单个查询,一系列查询和/或添加辅助表中执行此操作,这将产生快速结果? 或者我是否必须转储我想要的超集,然后使用我的(非SQL)编程语言构造最终输出?

TIA

在SQLITE3中测试,您的数据库实现可能会有所不同

SELECT   m.date, 
         s.symbol, 
         s.open, 
         s.high, 
         s.low, 
         s.close, 
         s.volume
FROM     masterdate AS m LEFT OUTER JOIN 
         stockdata AS s ON m.date = s.date
AND      s.symbol = 'Foo'
WHERE    m.date >= (SELECT MIN(date) FROM stockdata WHERE symbol = 'Foo')
AND      m.date <= (SELECT MAX(date) FROM stockdata WHERE symbol = 'Foo')

如果这不能足够快地执行,那么您可以通过在一个查询中设置最小值和最大值的变量然后在主查询中使用这些变量来提高性能。 这样可以为您节省至少一个索引。

所以(在SQL Server语法中)

SET @symbol = 'Foo'

SELECT @mindate = MIN(date),
       @maxdate = MAX(date)
FROM   stockdata
WHERE  stockdata.symbol = @symbol


SELECT   m.date, 
         s.symbol, 
         s.open, 
         s.high, 
         s.low, 
         s.close, 
         s.volume
FROM     masterdate AS m LEFT OUTER JOIN 
         stockdata AS s ON m.date = s.date
AND      s.symbol = @symbol
WHERE    m.date BETWEEN @mindate AND @maxdate

您还需要确保在masterdate.date上有索引,在stockdata(日期,符号)上有一个复合索引。

这是一个经典的左连接:

SELECT * FROM masterdates
    LEFT JOIN stockdata ON masterdates.date = stockdata.date;

显然,这应该被细化为仅返回所需的列。

如果使用SQLServer,则可以使用TSQL存储过程来获取结果。 它基本上有两行:

1)获取可用数据的第一个日期2)具有外部联接的查询

如果您使用Oracle,则可以使用PL / SQL编写类似(虽然稍微复杂一点)的存储过程来计算您想要的答案。

我建议填写Stockdata表中缺少的条目并使用内部联接。 应该快得多。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM