【问题标题】:joining two table not working as expected加入两个表没有按预期工作
【发布时间】:2018-10-21 06:08:23
【问题描述】:

我已经为此工作了大约两天,但似乎无法弄清楚,所以我希望得到一些帮助。

我有两张桌子:

mysql> select id, date, volume, symbol_id  from control_quotedaily limit 5;
+-------+---- -------+----------+-----------+
| id    | date       | volume   | symbol_id |
+-------+------------+----------+-----------+
| 13263 | 2017-11-02 |  7800191 | AXISBANK  |
| 13264 | 2017-11-02 |  9303981 | SBIN      |
| 13265 | 2017-11-02 |  8013536 | HDFCBANK  |
| 13266 | 2017-11-03 |  9642624 | AXISBANK  |
| 13267 | 2017-11-04 | 19642327 | AXISBANK  |
+-------+------------+----------+-----------+
5 rows in set (0.00 sec)
14 rows in set (0.01 sec)

mysql> select * from control_oidaily
+-----------+------------+-------------+--------------+
| symbol_id | date       | expiry_date | val_in_lakhs |
+-----------+------------+-------------+--------------+
| AXISBANK  | 2017-11-02 | 2017-11-30  |     166881.8 |
| AXISBANK  | 2017-11-02 | 2017-12-28  |      2676.84 |
| AXISBANK  | 2017-11-02 | 2018-01-25  |        97.13 |
| HDFCBANK  | 2017-11-02 | 2017-11-30  |     76351.11 |
| HDFCBANK  | 2017-11-02 | 2017-12-28  |      1509.48 |
| HDFCBANK  | 2017-11-02 | 2018-01-25  |            0 |
| SBIN      | 2017-11-02 | 2017-11-30  |      88654.3 |
| SBIN      | 2017-11-02 | 2017-12-28  |      1060.51 |
| SBIN      | 2017-11-02 | 2018-01-25  |            0 |
| AXISBANK  | 2017-11-03 | 2017-11-30  |     87640.06 |
+-----------+------------+-------------+--------------+

所以对于 control_quotedai​​ly 表中的每个报价,这就是我想要的:

  1. control_oidaily 表中该报价的最接近到期​​日期
  2. 我想要那个 expiry_date 的 val_in_lakhs。

例如:对于日期 2017-11-02,最接近的到期日是 2017-11-30,我希望返回 val_in_lakhs (76351.11)。

这就是我正在尝试的:

select o.date, o.expiry_date as expiry_date, o.symbol_id, q.date, q.symbol_id, o.val_in_lakhs, q.tottrdval, q.volume, q.symbol_id
FROM control_oidaily o
JOIN ( select o.date, MIN(expiry_date) as expiry_date, symbol_id
    FROM control_oidaily o
    GROUP by o.date,o.symbol_id                 
    ORDER BY o.date asc) as ed
ON ed.date = o.date 
    AND ed.symbol_id = o.symbol_id
    AND ed.expiry_date = o.expiry_date
JOIN control_quotedaily q
ON q.date = ed.date
    AND q.symbol_id = ed.symbol_id

这是我期待的输出:

+-------+------------+----------+-----------+--------------+--------------+
| id    | date       | volume   | symbol_id | expiry_date  | val_in_lakhs |
+-------+------------+----------+-----------+--------------+--------------+
| 13263 | 2017-11-02 |  7800191 | AXISBANK  | 2017-11-30   |     166881.8 |
| 13264 | 2017-11-02 |  9303981 | SBIN      | 2017-11-30   |      88654.3 |
| 13265 | 2017-11-02 |  8013536 | HDFCBANK  | 2017-11-30   |     76351.11 |
| 13266 | 2017-11-03 |  9642624 | AXISBANK  | 2017-11-30   |     87640.06 |
+-------+------------+----------+-----------+--------------+--------------+

【问题讨论】:

  • expiry_date 列是哪种数据类型??您提供的样本的实际结果是什么(2017-11-02,最近的到期时间是 2017-11-30???
  • 什么版本的 MySQL? (重要,v8 现在可用)最接近是否意味着小于或等于?表control_quotedaily 是否包含expiry_date 列? (你不显示它。)
  • 2017-11-30有3个到期日,为什么你会优先选择76351.11而不是另外两个?
  • expiry_date 的数据类型是日期时间。最接近的大于或等于
  • 在没有顶部/限制的子查询中排序是 nop。 PS请通过帖子编辑澄清,而不是cmets。谷歌“stackexchange 通知”,了解如何让非发帖用户通知您发表了评论。

标签: mysql database relational-database self-join jointable


【解决方案1】:
  • Derived Table 中,从control_oidaily 表中获取closest_expiry_date(最小值为expiry_date),用于symbol_iddate 的分组。
  • 将其与symbol_iddate 上的control_quotedaily 表连接,以获取control_quotedaily 表中每一行的最接近到期​​日期值。
  • 现在,再次使用同一个派生表与control_oidaily 表连接,匹配dateexpiry_date(具有最接近的到期日期)和symbol_id 以获得val_in_lakhs

您可能需要以下查询:

SELECT q.id, 
       q.`date`, 
       q.volume, 
       q.symbol_id, 
       o1.expiry_date, 
       o1.val_in_lakhs 
FROM control_quotedaily AS q 
JOIN (SELECT o2.`date`, 
             o2.symbol_id
             MIN(o2.expiry_date) as closest_expiry_date              
      FROM control_oidaily AS o2
      GROUP by o2.`date`, o2.symbol_id                 
     ) AS dt 
  ON dt.`date` = q.`date` 
     AND dt.symbol_id = q.symbol_id
JOIN control_oidaily AS o1 
  ON dt.`date` = o1.`date`
     AND dt.symbol_id = o1.symbol_id 
     AND dt.closest_expiry_date = o1.expiry_date 

【讨论】:

  • 太棒了!非常感谢!
  • 对不起,但仔细检查这不起作用:(
  • @avrgeo 有什么问题?你能创建一个 DB Fiddle 或 SQL fiddle 来测试吗?
  • 我已经用更多符号更新了描述。您的查询只返回我的 AXISBANK 也是如此。我无法为所有符号获得它。也许你可以再看看,再次感谢您的帮助
  • 谢谢,我已经编辑了评论并添加了想要的输出。我没有使用过 db-fiddle 但会尝试一下
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-04-24
  • 2016-07-23
  • 1970-01-01
  • 2012-04-25
  • 1970-01-01
  • 2021-10-19
相关资源
最近更新 更多