【问题标题】:Join most recent record before time in primary table在主表中加入时间之前的最新记录
【发布时间】:2018-03-22 03:25:22
【问题描述】:

我知道“如何加入最新记录”的问题被问了很多,但是,这个问题超出了我的知识范围。我通常使用“加入最大日期子查询,然后加入具有匹配 id 和时间的行”的方法来解决问题,并且我可以在子查询的 where 子句中添加额外的条件,但是这种风格在这个中不起作用情况。

我正在寻找第一个表中所有记录的历史记录,并在第一个表的记录时间之前加入第二个表的最新记录。

例子:

CREATE TABLE `A` (
  `id` int(11) NOT NULL,
  `a_time` timestamp NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

INSERT INTO `A` (`id`, `a_time`) VALUES
(1, '2018-03-21 04:30:00'),
(2, '2018-03-21 05:30:00'),
(3, '2018-03-21 07:30:00'),
(4, '2018-03-21 12:30:00');

CREATE TABLE `B` (
  `id` int(11) NOT NULL,
  `b_time` timestamp NOT NULL,
  `some_text` varchar(128) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

INSERT INTO `B` (`id`, `b_time`, `some_text`) VALUES
(1, '2018-03-21 05:30:00', 'Foo'),
(2, '2018-03-21 09:30:00', 'Bar');


ALTER TABLE `A`
  ADD PRIMARY KEY (`id`);

ALTER TABLE `B`
  ADD PRIMARY KEY (`id`);

我希望的是来自 A 的 id 和时间,以及来自 B 的最新 (

a.id a.a_time            b.some_text
------------------------------------
1    2018-03-21 04:30:00 null
2    2018-03-21 05:30:00 Foo
3    2018-03-21 07:30:00 Foo
4    2018-03-21 12:30:00 Bar

有人可以帮我解决这个问题吗?谢谢!

【问题讨论】:

  • 看到 OP 的最大努力总是很高兴
  • 看来唯一的选择是相关子查询。这句话让我害怕,因为它的效率。

标签: mysql join


【解决方案1】:

我会使用这样的“相关子查询”:

查询 1

select
       a.*
    , (select b.some_text from b
       where b.b_time <= a.a_time
       order by b.b_time DESC
       limit 1) as some_text
from a
order by a.id

Results

| id |               a_time | some_text |
|----|----------------------|-----------|
|  1 | 2018-03-21T04:30:00Z |    (null) |
|  2 | 2018-03-21T05:30:00Z |       Foo |
|  3 | 2018-03-21T07:30:00Z |       Foo |
|  4 | 2018-03-21T12:30:00Z |       Bar |

【讨论】:

  • 如何避免相关子查询的性能损失?我可以索引它以避免重复的表扫描吗?
  • 你可以试试草莓提供的方法。建议在任一方法中对 a_time 和 b_time 列进行索引
【解决方案2】:

我可能会使用未关联的子查询,如下所示:

SELECT x.some
     , c.columns
     , y.some_column
  FROM 
     ( SELECT a.*
            , MAX(b.b_time) b_time 
         FROM a
         LEFT 
         JOIN b 
           ON b.b_time <= a.a_time 
        GROUP 
           BY id
     ) x 
  LEFT 
  JOIN b y 
    ON y.something = x.something;
+----+---------------------+-----------+
| id | a_time              | some_text |
+----+---------------------+-----------+
|  1 | 2018-03-21 04:30:00 | NULL      |
|  2 | 2018-03-21 05:30:00 | Foo       |
|  3 | 2018-03-21 07:30:00 | Foo       |
|  4 | 2018-03-21 12:30:00 | Bar       |
+----+---------------------+-----------+

【讨论】:

    猜你喜欢
    • 2012-01-06
    • 2012-05-11
    • 1970-01-01
    • 2010-10-27
    • 1970-01-01
    • 2021-03-16
    • 2018-02-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多