【问题标题】:Calculating MAX from specific date range on a JOIN从 JOIN 的特定日期范围计算 MAX
【发布时间】:2017-12-16 11:01:41
【问题描述】:

我已经为此苦苦挣扎了 6 个小时,这让我发疯。我已经求救了...

我正在研究股票价格,并且每隔 10 分钟就有一排交易价格(要价、日期时间、名称等)。我想获取每笔交易的清单,以及该笔交易在接下来的一小时内的交易价格。

以下是我迄今为止一直在玩的。我想添加一个返回 MAX 价格的“max”列。 - 目前,下面的查询返回JOIN 中的所有交易(重复c.id),而不是带有MAX 列的单个交易。

如果我将 JOIN 与 limit 1 一起使用,我会因为 a.market = c.market 而得到 NULL 值,如果我使用 MAX(),我会遇到分组错误,无论我做什么,我都无法让它工作。如果改变任何答案,ql_mode=only_full_group_by 也会打开。

样本数据/查询:http://sqlfiddle.com/#!9/9c61f4/1

SELECT 
c.id, 
c.ask AS trade_cost_at_time, 
c.timestamp, 
a.ask AS next_hour_top_price,
a.timestamp AS next_hour_top_price_time 
FROM trade_data c
    JOIN (
        SELECT l1.market, l1.ask, l1.timestamp FROM trade_data l1 
    ) a ON a.market = c.market AND a.timestamp BETWEEN DATE_FORMAT(DATE(c.timestamp), "%Y-%m-%d %H:%i:%s") AND DATE_FORMAT(DATE_ADD(DATE(c.timestamp), INTERVAL 100 HOUR), "%Y-%m-%d %H:%i:%s")

基于上述 SQLFiddle 的预期结果是:

id | trade_cost_at_time | timestamp | next_hour_top_price | next_hour_top_price_time

1604 | 0.00001212 | 2017-12-15 16:30:03 | 0.00001220
1804 | 0.00001220 | 2017-12-15 16:40:02 | 0.00001218
2004 | 0.00001218 | 2017-12-15 17:00:02 | 0.00001205
...
5588 | 0.00001171 | 2017-12-15 20:10:02 | 0.00001184
...
10777 | 0.00001204 | 2017-12-16 00:10:03 | 0.00001199
11177 | 0.00001199 | NULL | NULL 

提前致谢。

【问题讨论】:

  • 嗨。您似乎需要按交易分组,并找到某个行子集的最大值。 “分组错误”是什么意思?你尝试了什么?什么甚至可以识别该表中的“交易”,因为它是一个时间和高度在该时间 10 英寸以内的事物?花更多时间解释基于输入的输出应该如何 - 就好像你在告诉有人清楚地可以离开并带着一个程序回来做那个 - 因为你是。请阅读并采取行动minimal reproducible example
  • @philipxy 我已经更新了 SQLFiddle 并给出了预期的结果。 group by 错误围绕“这与 sql_mode=only_full_group_by 不兼容”。我不认为把我尝试过的东西放在这里会有什么好处,而且我已经没有它们了。
  • 这样的分组错误来自无意义的分组,但是通过这样的步骤解释你试图完成的事情可能有助于解释你想要的部分。
  • 请解决我所有的第一条评论——解释一下。所以输出是输入加上一个最大列? “那笔交易”是什么意思?整张桌子是一个“交易”吗?那么为什么是“所有交易”呢?我们怎么知道什么时间和成本(又名价格?)适用于什么“交易”?也许我们一天中的每个小时都分组?我们必须从您不清楚的描述中猜测。您提供大量而不是最少的数据,期望我们在猜测模式的无法解释的群体中最大化,而您在我们还不知道输出时忽略输出。为什么我们要弄清楚你什么时候不指导我们?如果你不能用语言说,你怎么能用代码呢?
  • 不是你期望的结果,而是陈述期望的结果。

标签: mysql sql


【解决方案1】:

我不确定 10 分钟的间隔,所以我 created a numbers table 可以生成 10 分钟的间隔范围。您可能不需要这个,或者您可能已经有了替代方法。无论如何,以下查询在 2 个阶段使用 2 个相关子查询。第一个是获取下一小时内的max(ask) 值,然后第二个使用该值与达到该价格的那个小时内的min(timestamp) 匹配。

SQL Fiddle 提供演示

查询 1

select
       *
     , (select min(nxt.timestamp) from trade_data nxt
        where nxt.market = d.market 
             and nxt.timestamp > d.start_time
             and nxt.timestamp < date_add(d.start_time, interval 1 hour) 
             and nxt.ask = d.next_hour_top_price
             limit 1
            ) as next_hour_top_time
from (
      select
            tr.n
          , td.market
          , tr.start_time
          , coalesce(min(td.ask),0) ask
          , count(td.timestamp) num_trades
          , (select max(nxt.ask) from trade_data nxt
            where nxt.market = td.market 
            and nxt.timestamp > tr.start_time
            and nxt.timestamp < date_add(tr.start_time, interval 1 hour) 
            limit 1
            ) as next_hour_top_price
      from (
             -- generate table of time ranges
             select n
                  , date_add(str_to_date('2017-12-15 16:00','%Y-%m-%d %H:%i'), interval (n*10) minute) as start_time
                  , date_add(str_to_date('2017-12-15 16:00','%Y-%m-%d %H:%i'), interval ((n+1)*10) minute) as end_time
             from numbers
             where n between 0 and 60
             ) tr
      left outer join trade_data td on td.timestamp >= tr.start_time and td.timestamp < tr.end_time
      group by tr.n, td.market, tr.start_time
      ) d
;

Results

|  n |     market |       start_time |        ask | next_hour_top_price |   next_hour_top_time |
|----|------------|------------------|------------|---------------------|----------------------|
|  0 |     (null) | 2017-12-15 16:00 |          0 |              (null) |               (null) |
|  1 |     (null) | 2017-12-15 16:10 |          0 |              (null) |               (null) |
|  2 | STOCK-NAME | 2017-12-15 16:20 | 0.00001212 |           0.0000122 | 2017-12-15 16:30:03Z |
|  3 | STOCK-NAME | 2017-12-15 16:30 |  0.0000122 |           0.0000122 | 2017-12-15 16:30:03Z |
|  4 | STOCK-NAME | 2017-12-15 16:40 | 0.00001218 |          0.00001218 | 2017-12-15 16:40:02Z |
|  5 | STOCK-NAME | 2017-12-15 16:50 | 0.00001201 |          0.00001205 | 2017-12-15 17:00:02Z |
|  6 | STOCK-NAME | 2017-12-15 17:00 | 0.00001205 |          0.00001205 | 2017-12-15 17:00:02Z |
|  7 | STOCK-NAME | 2017-12-15 17:10 | 0.00001204 |          0.00001204 | 2017-12-15 17:10:02Z |
|  8 | STOCK-NAME | 2017-12-15 17:20 | 0.00001194 |            0.000012 | 2017-12-15 18:00:02Z |
|  9 | STOCK-NAME | 2017-12-15 17:30 |  0.0000118 |            0.000012 | 2017-12-15 18:00:02Z |
| 10 | STOCK-NAME | 2017-12-15 17:40 | 0.00001191 |            0.000012 | 2017-12-15 18:00:02Z |
| 11 | STOCK-NAME | 2017-12-15 17:50 | 0.00001199 |            0.000012 | 2017-12-15 18:00:02Z |
| 12 | STOCK-NAME | 2017-12-15 18:00 |   0.000012 |            0.000012 | 2017-12-15 18:00:02Z |
| 13 | STOCK-NAME | 2017-12-15 18:10 | 0.00001176 |          0.00001188 | 2017-12-15 18:20:02Z |
| 14 | STOCK-NAME | 2017-12-15 18:20 | 0.00001188 |          0.00001188 | 2017-12-15 18:20:02Z |
| 15 | STOCK-NAME | 2017-12-15 18:30 | 0.00001182 |          0.00001182 | 2017-12-15 18:30:02Z |
| 16 | STOCK-NAME | 2017-12-15 18:40 | 0.00001181 |          0.00001181 | 2017-12-15 18:40:03Z |
| 17 | STOCK-NAME | 2017-12-15 18:50 | 0.00001173 |          0.00001174 | 2017-12-15 19:30:02Z |
| 18 | STOCK-NAME | 2017-12-15 19:00 | 0.00001152 |          0.00001174 | 2017-12-15 19:30:02Z |
| 19 | STOCK-NAME | 2017-12-15 19:10 | 0.00001151 |          0.00001183 | 2017-12-15 20:00:02Z |
| 20 | STOCK-NAME | 2017-12-15 19:20 |  0.0000117 |          0.00001184 | 2017-12-15 20:10:02Z |
| 21 | STOCK-NAME | 2017-12-15 19:30 | 0.00001174 |          0.00001184 | 2017-12-15 20:10:02Z |
| 22 | STOCK-NAME | 2017-12-15 19:40 | 0.00001171 |          0.00001184 | 2017-12-15 20:10:02Z |
| 23 | STOCK-NAME | 2017-12-15 19:50 | 0.00001172 |          0.00001184 | 2017-12-15 20:10:02Z |
| 24 | STOCK-NAME | 2017-12-15 20:00 | 0.00001183 |          0.00001184 | 2017-12-15 20:10:02Z |
| 25 | STOCK-NAME | 2017-12-15 20:10 | 0.00001184 |          0.00001184 | 2017-12-15 20:10:02Z |
| 26 | STOCK-NAME | 2017-12-15 20:20 | 0.00001175 |          0.00001181 | 2017-12-15 21:00:02Z |
| 27 | STOCK-NAME | 2017-12-15 20:30 | 0.00001169 |          0.00001183 | 2017-12-15 21:20:02Z |
| 28 | STOCK-NAME | 2017-12-15 20:40 | 0.00001169 |          0.00001183 | 2017-12-15 21:20:02Z |
| 29 | STOCK-NAME | 2017-12-15 20:50 | 0.00001173 |          0.00001183 | 2017-12-15 21:20:02Z |
| 30 | STOCK-NAME | 2017-12-15 21:00 | 0.00001181 |          0.00001183 | 2017-12-15 21:20:02Z |
| 31 | STOCK-NAME | 2017-12-15 21:10 | 0.00001181 |          0.00001183 | 2017-12-15 21:20:02Z |
| 32 | STOCK-NAME | 2017-12-15 21:20 | 0.00001183 |          0.00001183 | 2017-12-15 21:20:02Z |
| 33 | STOCK-NAME | 2017-12-15 21:30 |  0.0000118 |          0.00001198 | 2017-12-15 22:20:02Z |
| 34 | STOCK-NAME | 2017-12-15 21:40 |  0.0000118 |            0.000012 | 2017-12-15 22:30:02Z |
| 35 | STOCK-NAME | 2017-12-15 21:50 |  0.0000118 |           0.0000122 | 2017-12-15 22:40:02Z |
| 36 | STOCK-NAME | 2017-12-15 22:00 | 0.00001179 |           0.0000124 | 2017-12-15 22:50:02Z |
| 37 | STOCK-NAME | 2017-12-15 22:10 |  0.0000118 |           0.0000124 | 2017-12-15 22:50:02Z |
| 38 | STOCK-NAME | 2017-12-15 22:20 | 0.00001198 |           0.0000124 | 2017-12-15 22:50:02Z |
| 39 | STOCK-NAME | 2017-12-15 22:30 |   0.000012 |           0.0000124 | 2017-12-15 22:50:02Z |
| 40 | STOCK-NAME | 2017-12-15 22:40 |  0.0000122 |           0.0000124 | 2017-12-15 22:50:02Z |
| 41 | STOCK-NAME | 2017-12-15 22:50 |  0.0000124 |           0.0000124 | 2017-12-15 22:50:02Z |
| 42 | STOCK-NAME | 2017-12-15 23:00 | 0.00001219 |          0.00001219 | 2017-12-15 23:00:03Z |
| 43 | STOCK-NAME | 2017-12-15 23:10 | 0.00001208 |          0.00001211 | 2017-12-15 23:50:02Z |
| 44 | STOCK-NAME | 2017-12-15 23:20 | 0.00001194 |          0.00001211 | 2017-12-15 23:50:02Z |
| 45 | STOCK-NAME | 2017-12-15 23:30 | 0.00001209 |          0.00001211 | 2017-12-15 23:50:02Z |
| 46 | STOCK-NAME | 2017-12-15 23:40 | 0.00001209 |          0.00001211 | 2017-12-15 23:50:02Z |
| 47 | STOCK-NAME | 2017-12-15 23:50 | 0.00001211 |          0.00001211 | 2017-12-15 23:50:02Z |
| 48 | STOCK-NAME | 2017-12-16T00:00 | 0.00001204 |          0.00001204 | 2017-12-16T00:00:02Z |
| 49 | STOCK-NAME | 2017-12-16T00:10 | 0.00001199 |          0.00001199 | 2017-12-16T00:10:03Z |
| 50 | STOCK-NAME | 2017-12-16T00:20 | 0.00001199 |          0.00001199 | 2017-12-16T00:20:02Z |

设置

CREATE TABLE `trade_data` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `market` varchar(255) DEFAULT NULL,
  `ask` decimal(20,8) DEFAULT NULL,
  `timestamp` datetime DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=11374 DEFAULT CHARSET=latin1;



INSERT INTO `trade_data` (`id`, `market`, `ask`, `timestamp`)
VALUES
    (1604, 'STOCK-NAME', 0.00001212, '2017-12-15 16:20:02'),
    (1804, 'STOCK-NAME', 0.00001220, '2017-12-15 16:30:03'),
    (2004, 'STOCK-NAME', 0.00001218, '2017-12-15 16:40:02'),
    (2204, 'STOCK-NAME', 0.00001201, '2017-12-15 16:50:02'),
    (2404, 'STOCK-NAME', 0.00001205, '2017-12-15 17:00:02'),
    (2603, 'STOCK-NAME', 0.00001204, '2017-12-15 17:10:02'),
    (2802, 'STOCK-NAME', 0.00001194, '2017-12-15 17:20:02'),
    (3001, 'STOCK-NAME', 0.00001180, '2017-12-15 17:30:04'),
    (3200, 'STOCK-NAME', 0.00001191, '2017-12-15 17:40:02'),
    (3399, 'STOCK-NAME', 0.00001199, '2017-12-15 17:50:02'),
    (3598, 'STOCK-NAME', 0.00001200, '2017-12-15 18:00:02'),
    (3797, 'STOCK-NAME', 0.00001176, '2017-12-15 18:10:03'),
    (3996, 'STOCK-NAME', 0.00001188, '2017-12-15 18:20:02'),
    (4195, 'STOCK-NAME', 0.00001182, '2017-12-15 18:30:02'),
    (4394, 'STOCK-NAME', 0.00001181, '2017-12-15 18:40:03'),
    (4593, 'STOCK-NAME', 0.00001173, '2017-12-15 18:50:02'),
    (4792, 'STOCK-NAME', 0.00001152, '2017-12-15 19:00:02'),
    (4991, 'STOCK-NAME', 0.00001151, '2017-12-15 19:10:03'),
    (5190, 'STOCK-NAME', 0.00001170, '2017-12-15 19:20:02'),
    (5389, 'STOCK-NAME', 0.00001174, '2017-12-15 19:30:02'),
    (5588, 'STOCK-NAME', 0.00001171, '2017-12-15 19:40:03'),
    (5787, 'STOCK-NAME', 0.00001172, '2017-12-15 19:50:02'),
    (5986, 'STOCK-NAME', 0.00001183, '2017-12-15 20:00:02'),
    (6185, 'STOCK-NAME', 0.00001184, '2017-12-15 20:10:02'),
    (6384, 'STOCK-NAME', 0.00001175, '2017-12-15 20:20:03'),
    (6583, 'STOCK-NAME', 0.00001169, '2017-12-15 20:30:02'),
    (6782, 'STOCK-NAME', 0.00001169, '2017-12-15 20:40:03'),
    (6981, 'STOCK-NAME', 0.00001173, '2017-12-15 20:50:02'),
    (7180, 'STOCK-NAME', 0.00001181, '2017-12-15 21:00:02'),
    (7379, 'STOCK-NAME', 0.00001181, '2017-12-15 21:10:03'),
    (7578, 'STOCK-NAME', 0.00001183, '2017-12-15 21:20:02'),
    (7777, 'STOCK-NAME', 0.00001180, '2017-12-15 21:30:02'),
    (7977, 'STOCK-NAME', 0.00001180, '2017-12-15 21:40:02'),
    (8177, 'STOCK-NAME', 0.00001180, '2017-12-15 21:50:03'),
    (8377, 'STOCK-NAME', 0.00001179, '2017-12-15 22:00:02'),
    (8577, 'STOCK-NAME', 0.00001180, '2017-12-15 22:10:02'),
    (8777, 'STOCK-NAME', 0.00001198, '2017-12-15 22:20:02'),
    (8977, 'STOCK-NAME', 0.00001200, '2017-12-15 22:30:02'),
    (9177, 'STOCK-NAME', 0.00001220, '2017-12-15 22:40:02'),
    (9377, 'STOCK-NAME', 0.00001240, '2017-12-15 22:50:02'),
    (9577, 'STOCK-NAME', 0.00001219, '2017-12-15 23:00:03'),
    (9777, 'STOCK-NAME', 0.00001208, '2017-12-15 23:10:03'),
    (9977, 'STOCK-NAME', 0.00001194, '2017-12-15 23:20:02'),
    (10177, 'STOCK-NAME', 0.00001209, '2017-12-15 23:30:02'),
    (10377, 'STOCK-NAME', 0.00001209, '2017-12-15 23:40:02'),
    (10577, 'STOCK-NAME', 0.00001211, '2017-12-15 23:50:02'),
    (10777, 'STOCK-NAME', 0.00001204, '2017-12-16 00:00:02'),
    (10977, 'STOCK-NAME', 0.00001199, '2017-12-16 00:10:03'),
    (11177, 'STOCK-NAME', 0.00001199, '2017-12-16 00:20:02');


-- create numbers table structure (very basic)
create table `numbers` (
  `n` int(11) not null,
  primary key (`n`)
) engine=InnoDB default charset=latin1;
-- insert generated number sequence (e.g., 1-1,000,000)
insert into `numbers`(n)
select @rownum:=@rownum+1
from (
   select 0 union select 1 union select 2 union select 3 
   union select 4 union select 5 union select 6 
   union select 7 union select 8 union select 9
) a, (
   select 0 union select 1 union select 2 union select 3 
   union select 4 union select 5 union select 6 
   union select 7 union select 8 union select 9
) b, (
   select 0 union select 1 union select 2 union select 3 
   union select 4 union select 5 union select 6 
   union select 7 union select 8 union select 9
) c, (
   select 0 union select 1 union select 2 union select 3 
   union select 4 union select 5 union select 6 
   union select 7 union select 8 union select 9
) d, (
   select 0 union select 1 union select 2 union select 3 
   union select 4 union select 5 union select 6 
   union select 7 union select 8 union select 9
) e, (
   select 0 union select 1 union select 2 union select 3 
   union select 4 union select 5 union select 6 
   union select 7 union select 8 union select 9
) f, (select @rownum:=-1) r
; 

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-11-19
    • 1970-01-01
    • 1970-01-01
    • 2020-04-18
    • 1970-01-01
    • 2021-11-12
    相关资源
    最近更新 更多