我想知道在mysql中执行以下操作的更好方法是什么:
如果我有一个具有以下结构和伪数据的表A:
+------------+-----+
| Dates | ID |
+------------+-----+
| 01/01/2017 | 123 |
| 02/01/2017 | 123 |
| 03/01/2017 | 123 |
| 04/01/2017 | 123 |
| 06/01/2017 | 123 |
| 07/01/2017 | 123 |
| 01/01/2017 | 124 |
| 02/01/2017 | 124 |
| 03/01/2017 | 124 |
| 04/01/2017 | 124 |
| 06/01/2017 | 124 |
| 07/01/2017 | 124 |
+------------+-----+
和带有一些信息的表B是我想要从中获取属性数据:
+------------+-----+-----------+
| Dates | ID | Attribute |
+------------+-----+-----------+
| 29/12/2016 | 123 | AA |
| 30/12/2016 | 123 | AB |
| 31/12/2016 | 123 | AC |
| 01/01/2017 | 123 | AD |
| 03/01/2017 | 123 | AF |
| 04/01/2017 | 123 | AA |
| 07/01/2017 | 123 | AF |
| 10/01/2017 | 123 | AC |
| 27/12/2016 | 124 | BA |
| 28/12/2016 | 124 | BB |
| 29/12/2016 | 124 | BC |
| 30/12/2016 | 124 | BD |
| 31/12/2016 | 124 | BE |
| 02/01/2017 | 124 | BF |
| 04/01/2017 | 124 | BA |
| 06/01/2017 | 124 | AA |
| 07/01/2017 | 124 | AC |
| 11/01/2017 | 124 | BF |
+------------+-----+-----------+
根据以下条件,一个人将如何联接这两个表以获得属性信息:
在表A中的许多记录中,表B中没有匹配的日期,因此不能直接和简单地连接ID和日期;
如果在表B中没有匹配的日期d,则对于表A中的给定ID,那么我需要从紧接的前一个日期获取属性(该前一个日期可以是前一天或日期d)前几天。
我想要获得的结果表如下所示:
+----------------------+---------------------+----------------------------+
| Dates (from table A) | ID ( from table A ) | Attribute ( from table B ) |
+----------------------+---------------------+----------------------------+
| 01/01/2017 | 123 | AD |
| 02/01/2017 | 123 | AD |
| 03/01/2017 | 123 | AF |
| 04/01/2017 | 123 | AA |
| 06/01/2017 | 123 | AA |
| 07/01/2017 | 123 | AF |
| 01/01/2017 | 124 | BE |
| 02/01/2017 | 124 | BF |
| 03/01/2017 | 124 | BF |
| 04/01/2017 | 124 | BA |
| 06/01/2017 | 124 | AA |
| 07/01/2017 | 124 | AC |
+----------------------+---------------------+----------------------------+
请注意,例如: 对于2017年2月1日的ID = 123,表B中没有任何记录,因此我需要从前一天获得属性,在这种情况下,这是从2017年1月1日开始的属性-属性= AD。
如您所见,这是类似于我的真实数据的伪数据,并且我的真实数据在每个表中都有数百个注册表。因此,我也在寻找一种可以很好地运行数据库的解决方案。我认为也许我们需要一个存储过程,该存储过程遍历表A的每一行并获得我期望的结果,这是一个好主意吗?同时,我想知道是否可以通过join操作来完成...我现在真的很困惑:)
我希望这个解释很清楚,如果以前已经回答过类似的问题,我深感抱歉。但是,我已经研究了这几天,并且进行了大量搜索,但是没有找到类似问题的答案。 预先感谢您的帮助。 干杯。
编辑:我更改了一个或多个therms注册表的记录。
答案 0 :(得分:1)
一种方法是使用相关子查询,例如
drop table if exists tb;
drop table if exists ta;
create table ta(Dates date, ID int);
insert into ta values
(str_to_date('01/01/2017','%d/%m/%Y'),123),
(str_to_date('02/01/2017','%d/%m/%Y'),123),
(str_to_date('03/01/2017','%d/%m/%Y'),123),
(str_to_date('04/01/2017','%d/%m/%Y'),123),
(str_to_date('06/01/2017','%d/%m/%Y'),123),
(str_to_date('07/01/2017','%d/%m/%Y'),123),
(str_to_date('01/01/2017','%d/%m/%Y'),124),
(str_to_date('02/01/2017','%d/%m/%Y'),124),
(str_to_date('03/01/2017','%d/%m/%Y'),124),
(str_to_date('04/01/2017','%d/%m/%Y'),124),
(str_to_date('06/01/2017','%d/%m/%Y'),124),
(str_to_date('07/01/2017','%d/%m/%Y'),124);
create table tb( Dates date, ID int ,Attribute varchar(2));
insert into tb values
( str_to_date('29/12/2016','%d/%m/%Y'),123 , 'AA'),
( str_to_date('30/12/2016','%d/%m/%Y'),123 , 'AB'),
( str_to_date('31/12/2016','%d/%m/%Y'),123 , 'AC'),
( str_to_date('01/01/2017','%d/%m/%Y'),123 , 'AD'),
( str_to_date('03/01/2017','%d/%m/%Y'),123 , 'AF'),
( str_to_date('04/01/2017','%d/%m/%Y'),123 , 'AA'),
( str_to_date('07/01/2017','%d/%m/%Y'),123 , 'AF'),
( str_to_date('10/01/2017','%d/%m/%Y'),123 , 'AC'),
( str_to_date('27/12/2016','%d/%m/%Y'),124 , 'BA'),
( str_to_date('28/12/2016','%d/%m/%Y'),124 , 'BB'),
( str_to_date('29/12/2016','%d/%m/%Y'),124 , 'BC'),
( str_to_date('30/12/2016','%d/%m/%Y'),124 , 'BD'),
( str_to_date('31/12/2016','%d/%m/%Y'),124 , 'BE'),
( str_to_date('02/01/2017','%d/%m/%Y'),124 , 'BF'),
( str_to_date('04/01/2017','%d/%m/%Y'),124 , 'BA'),
( str_to_date('06/01/2017','%d/%m/%Y'),124 , 'AA'),
( str_to_date('07/01/2017','%d/%m/%Y'),124 , 'AC'),
( str_to_date('11/01/2017','%d/%m/%Y'),124 , 'BF');
select ta.dates, ta.id,(select attribute from tb where tb.id = ta.id and tb.dates <= ta.dates order by tb.dates desc limit 1) attribute
from ta;
+------------+------+-----------+
| dates | id | attribute |
+------------+------+-----------+
| 2017-01-01 | 123 | AD |
| 2017-01-02 | 123 | AD |
| 2017-01-03 | 123 | AF |
| 2017-01-04 | 123 | AA |
| 2017-01-06 | 123 | AA |
| 2017-01-07 | 123 | AF |
| 2017-01-01 | 124 | BE |
| 2017-01-02 | 124 | BF |
| 2017-01-03 | 124 | BF |
| 2017-01-04 | 124 | BA |
| 2017-01-06 | 124 | AA |
| 2017-01-07 | 124 | AC |
+------------+------+-----------+
12 rows in set (0.01 sec)