两表对应关系的复杂SQL查询

Posted

技术标签:

【中文标题】两表对应关系的复杂SQL查询【英文标题】:Complex SQL query for correspondance between two tables 【发布时间】:2015-12-15 12:10:36 【问题描述】:

我仍在从事与我询问 my previous question on Stack Overflow 时相同的项目。我的 SQL 表在那个问题中有完整的描述,我希望你阅读这个来理解我的新问题。

现在的区别在于 tradesevents 这两个表不再同步:现在,时间并不完全对应两张桌子。不过,我知道两张表之间还是一一对应的,也就是说每笔交易都有对应的事件,但是有些事件 em> 不对应于交易

交易

  id |   time    |  price  | volume |   foo
-----+-----------+---------+--------+-------
 201 | 32400.524 |      53 |   2085 |   xxx
 202 | 32400.530 |      53 |   1162 |   xxx
 203 | 32400.531 |   52.99 |     50 |   xxx
 204 | 32401.532 |   52.91 |   3119 |   xxx
 205 | 32402.437 |   52.91 |   3119 |   xxx
 206 | 32402.832 |   52.91 |   3119 |   xxx
 207 | 32403.255 |   52.91 |   3119 |   xxx
 208 | 32404.242 |   52.92 |   3220 |   xxx
 209 | 32405.823 |   52.92 |   3220 |   xxx
 210 | 32406.839 |   52.92 |   3220 |   xxx

事件

   id |   time    |  price  | volume |  bar 
-----+-----------+---------+--------+------
 328 | 32399.345 |   52.91 |   3119 |  yyy
 329 | 32400.964 |   52.91 |   3119 |  yyy
 330 | 32401.194 |   52.91 |   3119 |  yyy
 331 | 32401.746 |   52.91 |   3119 |  yyy
 332 | 32401.823 |   52.91 |   3119 |  yyy
 333 | 32402.534 |   52.91 |   3119 |  yyy
 334 | 32402.876 |   52.92 |   3220 |  yyy
 335 | 32403.839 |   52.92 |   3220 |  yyy
 336 | 32404.634 |   52.92 |   3220 |  yyy
 337 | 32405.234 |   52.91 |   2501 |  yyy

我想要的是通过最小化交易和事件之间的时间差异来使两个表之间的对应关系。这是有道理的:如果有多个事件对应于交易量和价格,我们必须选择距离交易“时间最短”的事件。

我尝试做以下事情:

SELECT 
    t.*,
   (SELECT e.id
        FROM events o
        WHERE e.price = t.price
        AND e.volume = t.volume
        ORDER BY ABS(o.time - t.time)
        LIMIT 1
    ) as most_probable_corresponding_event_id
FROM trades t
ORDER BY t.time;

但问题是这个查询没有给出唯一的对应关系:相同的事件 e 可以为不同的交易 t1 和 t2 选择,如果这个事件是最接近交易 t1 和 t2 的。我想要的是独家通讯。

感谢您的帮助。

编辑:

我期望示例数据的输出是:

   trade_id | order_id |  price  | volume |  bar |   foo 
 -----------+----------+---------+--------+------+-------
      204   |   331    |   52.91 |   3119 |  xxx |   yyy
      205   |   333    |   52.91 |   3119 |  xxx |   yyy
      206   |   334    |   52.91 |   3119 |  xxx |   yyy
      207   |   335    |   52.92 |   3220 |  xxx |   yyy
      208   |   336    |   52.92 |   3220 |  xxx |   yyy
      209   |   337    |   52.92 |   3220 |  xxx |   yyy

【问题讨论】:

您可以添加您的预期输出吗? 我已经为示例数据添加了预期的输出。目的只是为了将 xxx 和 yyy 数据放在一张表中进行对应。 如果上下有两个对应关系,那么正确的对应关系是什么?比如,你的时间是:32399.345 还有32400.34532398.345 ? 二选一,假设我们选第一个。这是我上一个问题的目标,按时间、价格和数量进行划分,然后在第一个之间进行对应,然后在第二个之间进行对应,等等。 您的样本有误。 trade_id 206 和 event_id 304 之间没有对应关系,因为价格和数量不匹配 【参考方案1】:

我尝试了很多,但无法得到您的结果。不过我得到了一些可能会有所帮助的东西。

使用以下查询,您可以获得具有相同价格和交易量以及事件与交易之间的时间差的所有记录。

select *  from
(SELECT t.id as trade_id, e.id as event_id, e.price as price, e.volume as volume,e.bar as bar, t.foo as foo, abs(e.time-t.time) as diff 
FROM events e
inner JOIN trades t on t.price = e.price AND t.volume = e.volume order by trade_id,diff asc ) a

使用您的数据不可能获得您期望的一些结果。即 206 不能使用价格和数量匹配的 order_id 334。

我认为要克服大多数问题,您需要更改数据库并添加外键(以便更轻松地进行连接)

下面的查询会给你一个结果,但是 event_id 不匹配,要么是因为前面提到的问题(价格和数量匹配),要么是因为最接近时间匹配的事件记录不是你实际的记录想要。

select *  from
(SELECT t.id as trade_id, e.id as event_id, e.price as price, e.volume as volume,e.bar as bar, t.foo as foo, abs(e.time-t.time) as diff FROM events e 
inner JOIN trades t on t.price = e.price AND t.volume = e.volume order by trade_id,diff asc ) a group by trade_id

【讨论】:

【参考方案2】:

根据您在上一个问题中所写的内容以及示例数据,我预计事件表中的时间总是比交易表中的时间晚。因此,如果您添加一个事件时间 > 订单时间的条件,这应该会给您一个独特的匹配,除非事件表明显落后于交易。

SELECT 
t.*,
(SELECT e.id
    FROM events o
    WHERE e.price = t.price
    AND e.volume = t.volume
    AND o.time > t.time
    ORDER BY ABS(o.time - t.time)
    LIMIT 1
) as most_probable_corresponding_event_id
FROM trades t
ORDER BY t.time;

【讨论】:

以上是关于两表对应关系的复杂SQL查询的主要内容,如果未能解决你的问题,请参考以下文章

SQL两表查询用啥命令?

SQL 表的连接查询

这两个sql查询语句哪个更快?

两表关联查询SQL语句的,要怎么写?

sql多表连接查询问题

求助各位大神,sql server两表间一对多的关系,如何数据整合到一行数据中,问题举例在问题补充中。谢谢..