UPDATE语法求教

狼异族 2016-10-06 09:59:11
现有两个表 A (code,date, valueA,valueB) B(code,date,valueB)
现在需要对A表进行更新,更新逻辑是
A.valueB = A.valueA / B.valueB where A.code = B.code and B.date <= A.date
但是 B.date <= A.date 需要的是
select top 1 B.date from B left join A on A.code = B.code 
where B.date <= A.date order by date desc
这样的update语句怎么写
...全文
195 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
狼异族 2016-10-06
  • 打赏
  • 举报
回复
在网上看到个写法,但是发现效率不高, A表100w条记录 B表5w条记录 要5分钟
udpate  A set A.valueB = 
case when exists (select * from B where A.code = B.code and A.date >= B.date) 
then select top 1 valueB from B where A.code = B.code and A.date >= B.date order by B.date  desc
else select top 1 valueB from B where A.code = B.code  order by B.date  
end
狼异族 2016-10-06
  • 打赏
  • 举报
回复
引用 3 楼 wmxcn2000 的回复:
表 b 上有两个日期字段吗? date 和 hqdate ?
我写错了,只有个date
卖水果的net 2016-10-06
  • 打赏
  • 举报
回复
表 b 上有两个日期字段吗? date 和 hqdate ?
狼异族 2016-10-06
  • 打赏
  • 举报
回复
引用 1 楼 wmxcn2000 的回复:
-- 这个意思吗?
update a 
set a.col = (select top 1 b.col_value from b where a.id = b.id and a.date > b.date)
差不多这个意思,还有个复杂的情况 如果不存在
select top 1 b.col_value from b where a.id = b.id and a.date >= b.date
就采用
select top 1 b.col_value from b where a.id = b.id order by hqdate
这个怎么能够联合起来呢?
卖水果的net 2016-10-06
  • 打赏
  • 举报
回复
-- 这个意思吗?
update a 
set a.col = (select top 1 b.col_value from b where a.id = b.id and a.date > b.date)
道素 2016-10-06
  • 打赏
  • 举报
回复
仅考虑语句实现方法,效率暂不说,如果我理解没错,你要的数据也可以按照下面的方法取得,如下例子: 变量d就a表的日期(可以在update a表再cross apply一个下面方法操作b得到的子查询) 当传入的日期能找到b.d <= @d能找到数据时EaryCount大于0 这时取b.d <= @d数据范围内日期最新的那行 否则取该id下hqdate最早的那行值(将排序写到对应的row_number中)

 DECLARE @d DATETIME='10/3/2016'            
 ;WITH b(ID,value,d,hqdate) AS
 (
 	SELECT 1,1,CONVERT(DATETIME,'10/1/2016'),CONVERT(DATETIME,'8/1/2016') UNION ALL
 	SELECT 1,2,'10/2/2016','8/4/2016' UNION ALL
 	SELECT 1,3,'10/3/2016','8/9/2016' UNION ALL
 	SELECT 1,4,'10/4/2016','8/16/2016' UNION ALL
 	SELECT 1,5,'10/5/2016','8/29/2016' 
 )
 SELECT * FROM (
 	SELECT * 
 	   ,ROW_NUMBER() OVER (ORDER BY hqdate ) AS hq_rn
 	   ,ROW_NUMBER() OVER (ORDER BY CASE WHEN b.d <= @d THEN d ELSE NULL END desc ) AS rn
 	   ,COUNT(CASE WHEN b.d <= @d THEN d ELSE NULL END) OVER ( PARTITION BY id ) AS EaryCount
 	FROM b
 ) c WHERE 1=CASE WHEN c.EaryCount=0 THEN c.hq_rn ELSE rn END
狼异族 2016-10-06
  • 打赏
  • 举报
回复
引用 8 楼 wmxcn2000 的回复:
[quote=引用 7 楼 L812234929 的回复:] [quote=引用 6 楼 wmxcn2000 的回复:]

-- 那就把满足条件的,放在前面;
select top 1 valueB from B where A.code = B.code  
order by case when A.date >= B.date then 0 else 1 end,b.date
这个好像不对,如果有多个 B.date <= A.date 那不是选了b.date最小的一个记录了[/quote] 加个 desc 就可以了[/quote]但是如果只有B.date > A.date 则选择的是B.date最大的那一条记录啊
卖水果的net 2016-10-06
  • 打赏
  • 举报
回复
引用 7 楼 L812234929 的回复:
[quote=引用 6 楼 wmxcn2000 的回复:]

-- 那就把满足条件的,放在前面;
select top 1 valueB from B where A.code = B.code  
order by case when A.date >= B.date then 0 else 1 end,b.date
这个好像不对,如果有多个 B.date <= A.date 那不是选了b.date最小的一个记录了[/quote] 加个 desc 就可以了
狼异族 2016-10-06
  • 打赏
  • 举报
回复
引用 6 楼 wmxcn2000 的回复:

-- 那就把满足条件的,放在前面;
select top 1 valueB from B where A.code = B.code  
order by case when A.date >= B.date then 0 else 1 end,b.date
这个好像不对,如果有多个 B.date <= A.date 那不是选了b.date最小的一个记录了
卖水果的net 2016-10-06
  • 打赏
  • 举报
回复

-- 那就把满足条件的,放在前面;
select top 1 valueB from B where A.code = B.code  
order by case when A.date >= B.date then 0 else 1 end,b.date

22,210

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server 疑难问题
社区管理员
  • 疑难问题社区
  • 尘觉
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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