查找每个相同开始和结束周的MAX和MIN值

时间:2016-01-25 18:46:26

标签: mysql sql

我试图实现一个查询,在尝试每周查找MAX和MIN时,我没有取得多大成功。

我有两张桌子:

SYMBOL_DATA(包含open,high,low,close和volume) WEEKLY_LOOKUP(包含WEEK_START和WEEK_END的周(无周末)列表

**SYMBOL_DATA Example:**
OPEN, HIGH, LOW, CLOSE, VOLUME
23.22 26.99 21.45 22.49 34324995

WEEKLY_LOOKUP(包含带有WEEK_START和WEEK_END的周(无周末)列表

**WEEKLY_LOOKUP Example:**

WEEK_START  WEEK_END
2016-01-25  2016-01-29  
2016-01-18  2016-01-22
2016-01-11  2016-01-15
2016-01-04  2016-01-08

我试图找到每个WEEK_START和WEEK_END特定周的高点和低点。

例如,如果WEEK是WEEK_START = 2016-01-11和WEEK_END = 2016-01-15,我会有 列出该特定符号的5个条目:

DATE        HIGH     LOW
2016-01-15  96.38    93.54
2016-01-14  98.87    92.45
2016-01-13  100.50   95.21
2016-01-12  99.96    97.55
2016-01-11  98.60    95.39

2016-01-08  100.50   97.03
2016-01-07  101.43   97.30
2016-01-06  103.77   100.90
2016-01-05  103.71   101.67
2016-01-04  102.24   99.76

对于每周结束时(2016-01-15)2016-01-13的HIGH为100.50,2016-01-14的LOW为92.45

我试图编写一个查询,给出一个高点和低点的列表,但是当我尝试添加一个MAX(HIGH)时,我只返回了一行。 我尝试了一些我无法使查询工作的东西(某种无限运行类型)。现在,我只是给了我一个每天高点和低点的列表,而不是每周的累计,我不知道该怎么做。

select date, t1.high, t1.low 
from SYMBOL_DATA t1, WEEKLY_LOOKUP t2 
where symbol='ABCDE' and (t1.date>=t2.START_DATE and t1.date<=t2.END_DATE) 
                     and t1.date<=CURDATE() 
LIMIT 30;

如何每周(开始和结束)获得每周发现的High_Date,MAX(高)和Low_Date,MIN(LOW)?我可能不需要 符号的完整历史记录,所以限制为30或(30周)就足够了,所以我可以看到趋势。

如果我想知道例如每周MAX(高)和MIN(LOW)开始一周结束2016-01-15结果将显示

**Result:**
WEEK_ENDING 2016-01-15 100.50 2016-01-13 92.45 2016-01-14
WEEK_ENDING 2016-01-08 103.77 2016-01-06 97.03 2016-01-08
etc
etc

感谢各位拥有专业知识和知识。非常感谢你的帮助。

修改 一旦返回包含每周MAX(HIGH)和MIN(LOW)的周末结束列表,那么就可以从该结果集中找到MAX(HIGH)和MIN(LOW),这样它只返回1从30周的时间进入? 谢谢!

致Piotr

select part1.end_date,part1.min_l,part1.max_h,  s1.date, part1.min_l,s2.date from 
(
select t2.start_date, t2.end_date, max(t1.high) max_h, min(t1.low) min_l
from SYMBOL_DATA t1, WEEKLY_LOOKUP t2 
where symbol='FB' 
and t1.date<='2016-01-22' 
and (t1.date>=t2.START_DATE and t1.date<=t2.END_DATE)
group by t2.start_date, t2.end_date order by t1.date DESC LIMIT 1;
) part1, symbol_data s1, symbol_data s2
where part1.max_h = s1.high and part1.min_l = s2.low;

enter image description here 您会注意到,每周的最大值和最小值保持大致相同且不变,因为高和低的每周都应该不同。

4 个答案:

答案 0 :(得分:1)

SQL Fiddle

我在我的例子中缩写了一些你的名字。

每周获得高低都很简单;你只需要使用GROUP BY:

SELECT s1.symbol, w.week_end, MAX(s1.high) AS weekly_high, MIN(s1.LOW) as weekly_low
FROM weeks AS w
INNER JOIN symdata AS s1 ON s1.zdate BETWEEN w.week_start AND w.week_end
GROUP BY s1.symbol, w.week_end

<强> Results

| symbol |                  week_end | weekly_high | weekly_low |
|--------|---------------------------|-------------|------------|
|   ABCD | January, 08 2016 00:00:00 |      103.77 |      97.03 |
|   ABCD | January, 15 2016 00:00:00 |       100.5 |      92.45 |

不幸的是,获取高和低的日期需要您根据符号,周和值重新加入symbol_data表。甚至 不能胜任这项工作;你必须考虑可能有两天达到相同的高(或低)的可能性,并决定选择哪一个。我在高低的一周任意选择了第一次出现。因此,要获得第二级选择,您需要另一个GROUP BY。整个事情看起来像这样:

SELECT wl.symbol, wl.week_end, wl.weekly_high, MIN(hd.zdate) as high_date, wl.weekly_low, MIN(ld.zdate) as low_date
FROM (
  SELECT s1.symbol, w.week_start, w.week_end, MAX(s1.high) AS weekly_high, MIN(s1.low) as weekly_low
  FROM weeks AS w
  INNER JOIN symdata AS s1 ON s1.zdate BETWEEN w.week_start AND w.week_end
  GROUP BY s1.symbol, w.week_end) AS wl
INNER JOIN symdata AS hd 
  ON hd.zdate BETWEEN wl.week_start AND wl.week_end
  AND hd.symbol = wl.symbol
  AND hd.high = wl.weekly_high
INNER JOIN symdata AS ld
  ON ld.zdate BETWEEN wl.week_start AND wl.week_end
  AND ld.symbol = wl.symbol
  AND ld.low = wl.weekly_low
GROUP BY wl.symbol, wl.week_start, wl.week_end, wl.weekly_high, wl.weekly_low

<强> Results

| symbol |                  week_end | weekly_high |                 high_date | weekly_low |                  low_date |
|--------|---------------------------|-------------|---------------------------|------------|---------------------------|
|   ABCD | January, 08 2016 00:00:00 |      103.77 | January, 06 2016 00:00:00 |      97.03 | January, 08 2016 00:00:00 |
|   ABCD | January, 15 2016 00:00:00 |       100.5 | January, 13 2016 00:00:00 |      92.45 | January, 14 2016 00:00:00 |

答案 1 :(得分:1)

要获取全局高点和低点,只需从原始查询中删除EnglishTitle表:

weekly

<强> Results

SELECT wl.symbol, wl.high, MIN(hd.zdate) as high_date, wl.low, MIN(ld.zdate) as low_date
FROM (
  SELECT s1.symbol, MAX(s1.high) AS high, MIN(s1.low) as low
  FROM symdata AS s1 
  GROUP BY s1.symbol) AS wl
INNER JOIN symdata AS hd 
  ON hd.symbol = wl.symbol
  AND hd.high = wl.high
INNER JOIN symdata AS ld
  ON ld.symbol = wl.symbol
  AND ld.low = wl.low
GROUP BY wl.symbol, wl.high, wl.low

答案 2 :(得分:1)

周表似乎完全是多余的......

SELECT symbol
     , WEEK(zdate)
     , MIN(low) min
     , MAX(high) max_high 
  FROM symdata 
 GROUP 
    BY symbol, WEEK(zdate);

这是一个简化的例子。实际上,您可能会使用DATE_FORMAT或类似的东西。 http://sqlfiddle.com/#!9/c247f/3

答案 3 :(得分:0)

检查以下查询是否产生了所需的结果:

    select part1.end_date,part1.min_l,part1.max_h,  s1.date, part1.min_l,s2.date from 
    (
    select t2.start_date, t2.end_date, max(t1.high) max_h, min(t1.low) min_l
    from SYMBOL_DATA t1, WEEKLY_LOOKUP t2 
    where symbol='ABCDE' 
    and (t1.date>=t2.START_DATE and t1.date<=t2.END_DATE)
    group by t2.start_date, t2.end_date
    ) part1, symbol_data s1, symbol_data s2
    where part1.max_h = s1.high and part1.min_l = s2.low
and (s1.date >= part1.start_date and part1.end_date)
and (s2.date >= part1.start_date and part1.end_date)