SQL加入最新记录

时间:2018-05-30 12:49:24

标签: sql join greatest-n-per-group

我希望以这样的方式连接表:它只从其中一个表中获取最新记录:

以下是我的数据

Table_One:

+----+------+
| ID | Name |
+----+------+
|  1 | John |
|  2 | Tom  |
|  3 | Anna |
+----+------+

Table_two:

+----+----------+-----------+
| ID | Visit ID |   Date    |
+----+----------+-----------+
|  1 |     2513 | 5/5/2001  |
|  1 |    84654 | 10/5/2012 |
|  1 |      454 | 4/20/2018 |
|  2 |      754 | 4/5/1999  |
|  2 |      654 | 8/8/2010  |
|  2 |      624 | 4/9/1982  |
|  3 |     7546 | 7/3/1997  |
|  3 |   246574 | 6/4/2015  |
|  3 |    15487 | 3/4/2017  |
+----+----------+-----------+

加入后需要的结果:

+----+------+----------+-----------+
| ID | Name | Visit ID |   Date    |
+----+------+----------+-----------+
|  1 | John |      454 | 4/20/2018 |
|  2 | Tom  |      654 | 8/8/2010  |
|  3 | Anna |   246574 | 6/4/2015  |
+----+------+----------+-----------+

5 个答案:

答案 0 :(得分:0)

不同的数据库引擎有不同的方法可以从每个组的表2中获得第一行(您可以谷歌搜索" SQL窗口函数"以及您的产品)。由于您没有说明您使用它的引擎,因此无法提供最合适或最高效的解决方案。

以下方法应该适用于大多数或所有SQL引擎,但不会对大型数据集特别有效(它将受益于复合索引Table2(ID,Date))。有关如何为表指定别名的详细信息可能会在引擎之间有所不同,但您可以将其用作指南。窗口函数解决方案可能更有效。

 SELECT ID, Name, VisitID, Date FROM Table1 T1 INNER JOIN Table2 T2 +
   ON T1.ID = T2.ID 
   WHERE NOT EXISTS (SELECT * FROM Table2 T2B WHERE T2B.ID = T1.ID AND T2B.Date > T2.Date)

答案 1 :(得分:0)

您可以过滤"最新访问"使用

SELECT TABLE,MAX(DATE)FROM TABLE_TWO GROUP BY ID;

然后将其连接到TABLE_ONE(... ON .ID = .ID)以获取Name列,然后再次将其连接到TABLE_TWO(... ON ID = ID AND DATE = DATE)如果需要也可以选择VISIT_ID。

特定的DBMS可能具有专有/特殊扩展,通常用于允许优化器做得更好(例如,允许优化器理解可以消除"加入TABLE_TWO)。在这里思考SELECT TOP 1 ......等等。

答案 2 :(得分:0)

我怀疑你有 SQL Server ,如果有,那么你可以使用APPLY

select o.*, tt.*
from Table_One o 
cross apply ( select top 1 t.VisitDate, t.Date
              from table_two t
              where t.id = o.id
              order by t.date desc
            ) tt;

答案 3 :(得分:0)

if progress.value == progress.maximum

答案 4 :(得分:0)

我不是100%肯定这是否正确,因为访问ID可能只是把每条记录都扔回来。但是,您可以在此处找到一些很棒的文档:https://www.w3resource.com/sql/aggregate-functions/max-date.php

select t1.ID,t1.Name,t2.visit_ID, Max(t2.Date) from Table_Two t2
inner join Table_One t1
on(t2.ID=t1.ID)
group by t1.ID,t1.Name,t2.visit_ID

这样的事情应该可行,我认为这也和@Erwin Smout提议的一样

select a.ID, t1.Name, a.date,t2.Visit_ID (
select ID, max(date)'date' from Table_Two 
group by ID) a
inner join Table_One t1
    on( a.ID=t1.ID)
inner join Table_Two t2
    on(a.ID=t2.ID and a.Date=t2.Date)