SQL 连接到最新记录

问题描述 投票:0回答:7

我想以一种只从其中一个表获取最新记录的方式连接表:

以下是我的数据

表_一:

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

表_二:

+----+----------+-----------+
| 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  |
+----+------+----------+-----------+
sql sql-server greatest-n-per-group
7个回答
2
投票

我怀疑您有 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;

2
投票

不同的数据库引擎有不同的方法来获取每组表 2 的顶行(您可以在 google 上搜索“SQL 窗口函数”和您的产品)。由于您没有说明您正在使用什么引擎,因此不可能提供最合适或最高性能的解决方案。

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

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

1
投票
SELECT ID,Name,Visit_ID,Date
FROM
    (SELECT *, ROW_NUMBER() OVER(PARTITION BY ID Date DESC) as seq
    FROM Table2 LEFT OUTER JOIN
         Table1 ON Table2.ID = Table1.ID) as mainTable
WHERE seq = 1

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)

0
投票

您可以使用

过滤掉“最近访问”
SELECT ID,MAX(DATE) FROM TABLE_TWO GROUP BY ID;

然后将其连接到 TABLE_ONE (... ON .ID = .ID) 以选择“名称”列,然后再次将其连接到 TABLE_TWO (... ON ID=ID AND DATE=DATE)(如果您需要选择)也增加 VISIT_ID。

特定的 DBMS 可能具有专有/特殊的扩展,通常是为了让优化器做得更好(例如,允许优化器理解“可以消除连接回 TABLE_TWO”)。这里考虑 SELECT TOP 1 ...和之类的。


0
投票

这就是你问题的答案

SELECT t1.ID, t1.Name, t2.visit_id, t2.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
)

0
投票

这是Hasan 的答案的工作版本

SELECT ID, Name, [Visit ID], Date
FROM (
    SELECT
        t1.*, t2.[Visit ID], t2.Date,
        ROW_NUMBER() OVER(PARTITION BY t1.ID ORDER BY Date DESC) AS rn
    FROM Table_One t1
    JOIN Table_Two t2 ON t1.ID = t2.ID
) AS t
WHERE rn = 1;

输出为:

身份证 姓名 访问ID 日期
1 约翰 454 2018-04-20
2 汤姆 654 2010-08-08
3 安娜 15487 2017-03-04

注意:为 Anna 返回的行与问题中的行不同,因为所需的输出不正确!

这是一个db<>小提琴

© www.soinside.com 2019 - 2024. All rights reserved.