逻辑简单又拗口的需求,一条SQL能实现吗?高分

javalion 2007-12-11 09:53:11
两张表
t_1, t_2
t_1:
ID MID Date
1 NULL 2007-1-21
2 NULL 2007-3-25
3 NULL 2007-3-26

t_2:
ID Date
1 2007-1-22
2 2007-1-25
3 2007-1-29

需求是这样的,把t_1作为目标表,需要更新MID,MID的值来自t_2表,拿t_1第一条记录跟t_2比较,发现t_2没有一条记录的date小于2007-1-21,所以转到下一条记录2007-3-25,发现t_2中有2007-1-25和2007-1-29两条数据符合,但2007-1-29的日期更接近2007-3-25,把t_2的ID:3更新到t_1的ID:2的MID中,转到t_1的2007-3-26,因为t_2的2007-1-29已经给之前的数据更新过,所以不参与这次的比较,t_1:2007-3-26只跟t_2:2007-1-12和2007-1-25比较,所以应该把t_2:2007-1-25的ID:2更新到t_1:ID=3的MID中,得到最终结果为
t_1
ID MID Date
1 NULL 2007-1-21
2 3 2007-3-25
3 2 2007-3-26

个人认为仅靠1条sql无法达到这种需求,勉强做了这么一个SQL:
UPDATE a
SET mappingid =
(SELECT TOP 1 id
FROM t_2 b
WHERE b.date < a.date AND b.id NOT IN
(SELECT mappingid
FROM t_1
WHERE mappingid IS NOT NULL)
ORDER BY b.date DESC)
FROM t_1 a
WHERE a.mappingid IS NULL

发现,(SELECT TOP 1 id
FROM t_2 b
WHERE b.date < a.date AND b.id NOT IN
(SELECT mappingid
FROM t_1
WHERE mappingid IS NOT NULL)
ORDER BY b.date DESC)这条语句得出的集合基本没有变。

各位兄弟姐妹,这种需求能用一条sql实现吗?谢谢了
...全文
134 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
fcuandy 2007-12-12
  • 打赏
  • 举报
回复
不是上一条,是几前的记录.

有些东西可以理解,言传时不好表达..
fcuandy 2007-12-12
  • 打赏
  • 举报
回复
因为你的语句,跟我的语句比起来,少了最后一个的not exists,即比较t_2当前记录是否已被同它连接t_1的记录的上一条记录所使用.
max(data) 和你的 top 1 data order by data desc是一个道理.
javalion 2007-12-12
  • 打赏
  • 举报
回复
Hi, fcuandy:
你的这个sql正是我想要实现而不能实现的,这种效率更高。
能解释以下为什么我写的那个SQL实现错误吗?谢谢了,暂时只能在4天后才能加分给你了。
fcuandy 2007-12-11
  • 打赏
  • 举报
回复
贴子结的真快,才5分钟就结了.
fcuandy 2007-12-11
  • 打赏
  • 举报
回复
create table t_1(ID int,           MID  int,           Date datetime)
insert t_1 select 1, NULL, '2007-1-21'
insert t_1 select 2, NULL, '2007-3-25'
insert t_1 select 3, NULL, '2007-3-26'

create table t_2(ID int, Date datetime)
insert t_2 select 1, '2007-1-22'
insert t_2 select 2, '2007-1-25'
insert t_2 select 3, '2007-1-29'


--select a.*,b.*
update a set mid=b.id
from t_1 a
left join t_2 b
on b.date=
(select max(date) from t_2 x
where date<=a.date
and not exists(select 1 from t_1 y
where id<a.id and date>=x.date
and not exists(select 1 from t_2 where date>x.date and date<=y.date)
)
)
select * from t_1

drop table t_1,t_2
fcuandy 2007-12-11
  • 打赏
  • 举报
回复
9点50时刚跑.net版去了,没看到.看看.
javalion 2007-12-11
  • 打赏
  • 举报
回复
to wuxi_88
我从来没有在sql中使用游标,真的很惊叹于这种,也非常佩服您的sql功底,确实了得啊
谢谢你了。
dobear_0922 2007-12-11
  • 打赏
  • 举报
回复
中国风,燃烧你的激情!
正牌风哥 2007-12-11
  • 打赏
  • 举报
回复
create table t_1(ID int,           MID  int,           Date datetime)
insert t_1 select 1, NULL, '2007-1-21'
insert t_1 select 2, NULL, '2007-3-25'
insert t_1 select 3, NULL, '2007-3-26'

create table t_2(ID int, Date datetime)
insert t_2 select 1, '2007-1-22'
insert t_2 select 2, '2007-1-25'
insert t_2 select 3, '2007-1-29'


go
declare test cursor for
select ID,[Date] from t_1
declare @ID int,@Date datetime
open test
fetch next from test into @ID,@Date
while @@fetch_status=0
begin
update t_1
set MID=(select ID from t_2 where Date=(select max(Date) from T_2 where Date<t_1.Date and ID not in(select isnull(MID,'') from t_1)))
where
ID=@ID
fetch next from test into @ID,@Date
end
close test
deallocate test

--drop table dbo.t_2
select * from t_1

ID MID Date
----------- ----------- ------------------------------------------------------
1 NULL 2007-01-21 00:00:00.000
2 3 2007-03-25 00:00:00.000
3 2 2007-03-26 00:00:00.000

(所影响的行数为 3 行)


javalion 2007-12-11
  • 打赏
  • 举报
回复
兄弟说的是存储过程吧,呵呵,我也知道存储过程能实现,但要求不能用存储过程

游标能嵌套在SQL中吗?

如果一条sql无法实现,我就只能用程序来实现了
正牌风哥 2007-12-11
  • 打赏
  • 举报
回复
用游标循环update

34,593

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server相关内容讨论专区
社区管理员
  • 基础类社区
  • 二月十六
  • 卖水果的net
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧