我有一个如下构建的表:
dpTicker dpDate dpOpen dpHigh dpLow dpClose dpVolume dpAdjClose dpCreated dpModified
GLE.PA 2016-02-01 35.39 35.455 34.375 34.785 2951300 34.785 2016-02-06 13:33:40 2016-02-06 13:33:40
GLE.PA 2016-02-02 34.515 34.565 32.165 32.575 7353600 32.575 2016-02-06 13:33:40 2016-02-06 13:33:40
GLE.PA 2016-02-03 32.4 32.495 30.885 31.6 7007000 31.6 2016-02-06 13:33:40 2016-02-06 13:33:40
GLE.PA 2016-02-04 32.075 32.38 30.67 31.98 8181000 31.98 2016-02-06 13:33:40 2016-02-06 13:33:40
GLE.PA 2016-02-05 32.55 33.0 31.86 32.11 7056700 32.11 2016-02-06 13:33:40 2016-02-06 13:33:40
数据是每日股价信息,该表包含数百个代码(例如GLE.PA)。每个股票代码(例如GLE.PA)都有一个每个“营业日”的条目。
我的目标是从每日价格数据表中查询每月价格摘要。月度数据构建如下:
我设法通过在SQLite3中使用以下查询来查询特定月份的数据:
SELECT
strftime ('%Y-%m', dpDate) AS month,
(SELECT dpOpen
FROM DailyPrices
WHERE dpTicker = 'GLE.PA'
AND dpDate =
(SELECT min(dpDate)
FROM DailyPrices
WHERE strftime('%Y%m', dpDate) = '201509'
)
) AS Open,
max(dpHigh) AS High,
min (dpLow) AS Low,
(SELECT dpClose
FROM DailyPrices
WHERE dpTicker = 'GLE.PA'
AND dpDate =
(SELECT max(dpDate)
FROM DailyPrices
WHERE strftime('%Y%m', dpDate) = '201509'
)
) AS Close
FROM DailyPrices
WHERE dpTicker ='GLE.PA'
AND strftime('%Y%m', dpDate) = '201509';
查询的输出如下:
bash-3.2$ sqlite3 myShares < month.sql
month Open High Low Close
---------- ---------- ---------- ---------- ----------
2015-09 42.72 44.07 37.25 39.85
bash-3.2$
通过以下查询,我设法生成高和低的月度概览:
SELECT
strftime('%Y-%m', dpDate) AS Month,
max(dpHigh) AS High,
min(dpLow) AS Low
FROM DailyPrices
WHERE dpTicker ='GLE.PA'
GROUP BY strftime('%Y%m', update);
输出的快照如下所示:
bash-3.2$ sqlite3 myShares < monthly.sql
Month High Low
---------- ---------- ----------
2000-01 219.32 184.346
2000-02 206.43 181.977
2000-03 210.411 181.503
2000-04 221.405 197.805
2000-05 226.239 55.9199
...
通过以下查询,我设法提取正确的Open和类比正确的Close数据:
SELECT
strftime('%Y-%m', dpDate) AS Month,
dpOpen AS Open
FROM DailyPrices
WHERE dpTicker = 'GLE.PA'
AND dpDate IN
(SELECT min(dpDate)
FROM DailyPrices
WHERE dpTicker = 'GLE.PA'
GROUP BY strftime('%Y%m', dpDate)
);
输出的快照如下:
bash-3.2$ sqlite3 myShares < Open.sql
Month Open
---------- ----------
2000-01 218.846
2000-02 200.269
2000-03 206.525
2000-04 201.312
2000-05 215.908
...
我正在努力将查询month.sql和open.sql组合到一个查询中以获得以下输出:
Month Open High Low Close
------- ----- ----- ----- -----
2015-01 42.79 42.79 33.69 35.18
2015-02 35.39 35.46 26.61 32.42
2015-03 32.32 37.65 31.93 32.48
...
任何帮助解决这个问题的人都会非常感激。 最诚挚的问候
邯
答案 0 :(得分:1)
第一个查询涉及搜索的特定月份有三个位置。让我们删除子查询中的两个出现;这需要使用别名,以便我们可以按名称引用同一个表的其他实例:
SELECT
strftime ('%Y-%m', dpDate) AS month,
(SELECT dpOpen
FROM DailyPrices
WHERE dpTicker = 'GLE.PA'
AND dpDate =
(SELECT min(dpDate)
FROM DailyPrices AS DP2
WHERE strftime('%Y%m', DP2.dpDate) = strftime('%Y%m', DP1.dpDate)
)
) AS Open,
max(dpHigh) AS High,
min (dpLow) AS Low,
(SELECT dpClose
FROM DailyPrices
WHERE dpTicker = 'GLE.PA'
AND dpDate =
(SELECT max(dpDate)
FROM DailyPrices AS DP2
WHERE strftime('%Y%m', DP2.dpDate) = strftime('%Y%m', DP1.dpDate)
)
) AS Close
FROM DailyPrices AS DP1
WHERE dpTicker ='GLE.PA'
AND strftime('%Y%m', dpDate) = '201509';
现在只有最外层的查询需要知道月份,我们可以简单地用GROUP BY替换过滤器:
SELECT
strftime ('%Y-%m', dpDate) AS month,
(...) AS Open,
max(dpHigh) AS High,
min (dpLow) AS Low,
(...) AS Close
FROM DailyPrices
WHERE dpTicker ='GLE.PA'
GROUP BY strftime('%Y%m', dpDate);
请注意,使用ORDER BY / LIMIT:
可以简化打开/关闭子查询(SELECT dpOpen
FROM DailyPrices
WHERE dpTicker = 'GLE.PA'
AND ... dpDate ...
ORDER BY dpDate ASC
LIMIT 1) AS Open
答案 1 :(得分:0)
谢谢CL !!对于SQLite新手来说,这是一个很好的学习方法,特别是对于使用ALIASES。
您的建议通常会产生良好的效果,但是,在运行几个测试运行时,我注意到以下样式的偶然错误:
bash-3.2$ sqlite3 myShares < tst.sql
month Open High Low Close
---------- ---------- ---------- ---------- ----------
2006-03 75.4675 76.5852 70.4136 74.4956
2006-04 75.0787 75.9048 70.5108 72.7948
2006-05 77.0225 68.5184 70.7538
2006-06 70.5594 73.4751 64.7767 72.7462
2006-07 72.5518 75.2245 68.2269 74.0582
bash-3.2$
您可以注意到,2006年5月份的公开价格缺失。我确认数据确实存在:
bash-3.2$ sqlite3 myShares < test.sql
dpTicker dpDate dpOpen dpHigh dpLow dpClose dpVolume dpAdjClose dpCreated dpModified
---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ------------------- -------------------
BNP.PA 2006-04-26 72.0173 73.1835 72.0173 72.892 2623400 48.8861 2015-12-08 12:04:22 2015-12-08 12:04:22
BNP.PA 2006-04-27 73.8153 74.0096 72.5032 73.6209 6001400 49.375 2015-12-08 12:04:22 2015-12-08 12:04:22
BNP.PA 2006-04-28 73.4751 73.9611 72.6976 72.7948 4133300 48.8209 2015-12-08 12:04:22 2015-12-08 12:04:22
BNP.PA 2006-05-02 72.5518 73.5723 72.3574 73.2807 3085400 49.1468 2015-12-08 12:04:22 2015-12-08 12:04:22
BNP.PA 2006-05-03 73.8639 74.0096 72.5518 72.649 3290400 48.7231 2015-12-08 12:04:22 2015-12-08 12:04:22
BNP.PA 2006-05-04 72.892 73.5237 72.2602 73.3779 3640300 49.212 2015-12-08 12:04:22 2015-12-08 12:04:22
BNP.PA 2006-05-05 73.6209 74.8357 73.4751 74.7872 3255600 50.1572 2015-12-08 12:04:22 2015-12-08 12:04:22
bash-3.2$
对于SQLite数据库中的每个代码,我通常在16年内有大约4个错误。
就我的SQLite新手知识而言,表中的数据很好。
任何想法为什么偶尔会跳过摘要记录?一般来说,差价发生在开盘价上,但也会不时出现在收盘价上。
致以最诚挚的问候,
GAM
对于记录,以下是我执行的查询
SELECT
strftime ('%Y-%m', dpDate) AS month,
(SELECT dpOpen
FROM DailyPrices
WHERE dpTicker = 'BNP.PA'
AND dpDate =
(SELECT min(dpDate)
FROM DailyPrices AS DP2
WHERE strftime('%Y%m', DP2.dpDate) = strftime('%Y%m', DP1.dpDate)
)
ORDER BY dpDate ASC
LIMIT 1) AS Open,
max(dpHigh) AS High,
min (dpLow) AS Low,
(SELECT dpClose
FROM DailyPrices
WHERE dpTicker = 'BNP.PA'
AND dpDate =
(SELECT max(dpDate)
FROM DailyPrices AS DP2
WHERE strftime('%Y%m', DP2.dpDate) = strftime('%Y%m', DP1.dpDate)
)
) AS Close
FROM DailyPrices AS DP1
WHERE dpTicker ='BNP.PA'
AND strftime('%Y-%m', dpDate) > '2006-02'
AND strftime('%Y-%m', dpDate) < '2006-08'
GROUP BY strftime('%Y-%m', dpDate);