SQL连接到最近日期的行

时间:2014-10-15 02:59:20

标签: sql sqlite

我试图使用sqlite连接两个表格,这些表格的日期并不完美匹配。

对于左表中的给定组/日期,我想要从右表中加入相应的记录,并在左表之前加上日期。可能最容易用一个例子展示。

表1:

group     date      teacher
  a     1/10/00        1
  a     2/27/00        1
  b     1/7/00         1
  b     4/5/00         1
  c     2/9/00         2
  c     9/12/00        2

表2:

teacher    date    hair length
   1       1/1/00       4
   1       1/5/00       8
   1       1/30/00     20
   1       3/20/00    100
   2       1/1/00       0
   2       8/10/00     50

给我们:

group     date      teacher    hair length
  a     1/10/00        1           8
  a     2/27/00        1          20
  b     1/7/00         1           8
  b     4/5/00         1         100
  c     2/9/00         2           0
  c     9/12/00        2          50

2 个答案:

答案 0 :(得分:1)

首先,对于试图重现此问题的人来说,有一些sqlite语句:

 create table tablea (teachergroup varchar(1), date datetime, teacher int);

 insert into tablea (teachergroup, date, teacher) VALUES 
 ('a','2000-01-10',1),('a','2000-02-27',1),
 ('b','2000-01-07',1),('b','2000-04-05',1),
 ('c','2000-02-09',2),('c','2000-09-12',2);

 create table tableb (teacher int, date datetime, hair_length int);   

 insert into tableb (teacher, date, hair_length) VALUES 
 (1,'2000-01-01',4),(1,'2000-01-05',8),
 (1,'2000-01-30',20),(1,'2000-03-20',100),
 (2,'2000-01-01',0),(2,'2000-08-10',50);

现在,最简单的查询(虽然肯定不是一个非常高效的查询)会加入这两个表:

 select * 
 from tablea a 
 join tableb on a.teacher=b.teacher 
     and b.date in 
     (select max(date) from tableb where date < a.date and teacher=a.teacher);

你可以做的另一件事是更自由地加入表格:

select * from a join b on a.teacher=b.teacher and b.date<a.date;

然后使用您通常用于获取与最大日期对应的行的任何技术。 (比如将它放入一个临时表中,然后使用一个组获取最小日期,然后将其连接到临时表以获取该行。我确定还有其他方法。)

答案 1 :(得分:1)

如果头发长度总是会变长,那么你可以这样做:

select tablea.teachergroup, tablea.date, tablea.teacher,
       max(tableb.hair_length)
from tablea
join tableb
on tablea.teacher=tableb.teacher
and tablea.date>=tableb.date
group by tablea.teachergroup, tablea.date, tablea.teacher

这可能适用于您的样本数据,但如果头发长度变短,您必须:

select a.teachergroup, a.date, a.teacher,
       tableb.hair_length
from (select tablea.teachergroup, tablea.date, tablea.teacher,
       max(tableb.date) as tdate   -- last date before group date
      from tablea
      join tableb
        on tablea.teacher=tableb.teacher
       and tablea.date>=tableb.date
     group by tablea.teachergroup, tablea.date, tablea.teacher
     ) as a
join tableb
on   a.teacher=tableb.teacher
and  a.tdate=tableb.date

这是迄今为止我能做到的有效方式。