求SQL语句:两表的关联,并取最大值的.

时间:2022-09-21 15:12:26
tab1
ID  stuname  
1    mike
2    john
3    cake


tab2
id   stuid  visitdate     disc
1     1      2009-2-3     演示
2     2      2009-12-12   传真  
3     2      2009-4-2     上门
4     3      2009-4-2     电话
5     1      2009-8-30    来访
6     2      2009-7-19    吃饭
7     3      2009-4-2     演示

我想要一SQL语名,查询出上两个表的数据是这个人的最后一次的visitdate,如果visitdate相同,则取最大ID的,如下所示:
ID  stuname  visitdate     disc
1    mike    2009-8-30     来访
2    john    2009-12-12    传真
3    cake    2009-4-2      演示

请问这个SQL怎么写呀?

7 个解决方案

#1


--> 测试数据:#1
if object_id('tempdb.dbo.#1') is not null drop table #1
create table #1(ID int, stuname varchar(8))
insert into #1
select 1, 'mike' union all
select 2, 'john' union all
select 3, 'cake'
--> 测试数据:#2
if object_id('tempdb.dbo.#2') is not null drop table #2
create table #2(id int, stuid int, visitdate datetime, disc varchar(8))
insert into #2
select 1, 1, '2009-2-3', '演示' union all
select 2, 2, '2009-12-12', '传真' union all
select 3, 2, '2009-4-2', '上门' union all
select 4, 3, '2009-4-2', '电话' union all
select 5, 1, '2009-8-30', '来访' union all
select 6, 2, '2009-7-19', '吃饭' union all
select 7, 3, '2009-4-2', '演示'

select a.*, b.visitdate, b.disc from #1 a inner join #2 b on a.id = stuid
where b.id = (select max(id) from #2 c where stuid=b.stuid and not exists (select 1 from #2 where stuid=c.stuid and visitdate>c.visitdate))

/*
ID          stuname  visitdate               disc
----------- -------- ----------------------- --------
1           mike     2009-08-30 00:00:00.000 来访
2           john     2009-12-12 00:00:00.000 传真
3           cake     2009-04-02 00:00:00.000 演示
*/

#2


这个太复杂了吧?有没有简单些的呀?

#3


用到not exists ,执行的效率会比较低呀.

#4


引用 3 楼 rings2000 的回复:
用到not exists ,执行的效率会比较低呀.

测测看吧

#5


你要找最大时间的并且可能不是唯一值,要么用 max(visitdate ) group by 得出一个子查询结果,再与原表联接;
要么就用not exists内联接,没第三种思路。

group by 的效率可能更低,自己测试一下,哪种方法快用哪种。

#6


那全部改为连接看是否快一点

#7


try



SELECT A.*,B.* 
FROM #1 A 
LEFT JOIN (
SELECT aa.* FROM #2 aa INNER JOIN(
SELECT (SELECT MAX(ID) FROM #2 WHERE t.stuid=stuid AND MAX(t.visitdate)=visitdate) id FROM #2 t GROUP BY stuid
) bb ON(aa.ID=bb.ID)
) B ON(A.ID=B.stuid)

#1


--> 测试数据:#1
if object_id('tempdb.dbo.#1') is not null drop table #1
create table #1(ID int, stuname varchar(8))
insert into #1
select 1, 'mike' union all
select 2, 'john' union all
select 3, 'cake'
--> 测试数据:#2
if object_id('tempdb.dbo.#2') is not null drop table #2
create table #2(id int, stuid int, visitdate datetime, disc varchar(8))
insert into #2
select 1, 1, '2009-2-3', '演示' union all
select 2, 2, '2009-12-12', '传真' union all
select 3, 2, '2009-4-2', '上门' union all
select 4, 3, '2009-4-2', '电话' union all
select 5, 1, '2009-8-30', '来访' union all
select 6, 2, '2009-7-19', '吃饭' union all
select 7, 3, '2009-4-2', '演示'

select a.*, b.visitdate, b.disc from #1 a inner join #2 b on a.id = stuid
where b.id = (select max(id) from #2 c where stuid=b.stuid and not exists (select 1 from #2 where stuid=c.stuid and visitdate>c.visitdate))

/*
ID          stuname  visitdate               disc
----------- -------- ----------------------- --------
1           mike     2009-08-30 00:00:00.000 来访
2           john     2009-12-12 00:00:00.000 传真
3           cake     2009-04-02 00:00:00.000 演示
*/

#2


这个太复杂了吧?有没有简单些的呀?

#3


用到not exists ,执行的效率会比较低呀.

#4


引用 3 楼 rings2000 的回复:
用到not exists ,执行的效率会比较低呀.

测测看吧

#5


你要找最大时间的并且可能不是唯一值,要么用 max(visitdate ) group by 得出一个子查询结果,再与原表联接;
要么就用not exists内联接,没第三种思路。

group by 的效率可能更低,自己测试一下,哪种方法快用哪种。

#6


那全部改为连接看是否快一点

#7


try



SELECT A.*,B.* 
FROM #1 A 
LEFT JOIN (
SELECT aa.* FROM #2 aa INNER JOIN(
SELECT (SELECT MAX(ID) FROM #2 WHERE t.stuid=stuid AND MAX(t.visitdate)=visitdate) id FROM #2 t GROUP BY stuid
) bb ON(aa.ID=bb.ID)
) B ON(A.ID=B.stuid)