update语句,相同时间加一秒,高手看过来。

rtsnd123 2015-08-14 11:03:41
--建立测试环境
create table a(id_no varchar(8),in_date datetime)
go
insert into a select '5791','2003-9-1 14:42:02'
union all select '5792','2003-9-1 14:42:02'
union all select '5794','2003-9-1 14:42:02'
union all select '5795','2003-9-1 14:42:03'
union all select '5796','2003-9-1 14:42:03'
union all select '5797','2003-9-1 14:42:03'
union all select '5831','2003-9-1 14:42:04'
union all select '5832','2003-9-1 14:42:04'
union all select '5833','2003-9-1 14:42:04'
union all select '5734','2003-9-1 14:42:02'
union all select '6792','2003-9-1 14:42:22'
union all select '6794','2003-9-1 14:42:22'
union all select '6795','2003-9-1 14:42:23'
union all select '6796','2003-9-1 14:42:23'
union all select '6797','2003-9-1 14:42:23'
union all select '6831','2003-9-1 14:42:34'
union all select '6832','2003-9-1 14:42:34'
union all select '6833','2003-9-1 14:42:54'
union all select '6734','2003-9-1 14:42:22'
go
要求是in_date字段中相同的时间加1秒,加完了不重复。


1、select * into # from a order by in_date

2、declare @date1 datetime,@date2 datetime,@date datetime
update #
set @date=case when @date2>=in_date or @date1=in_date
then dateadd(s,1,@date2) else in_date end,
@date1=in_date,@date2=@date,in_date=@date

3、update a set a.in_date=b.in_date from
a a join # b on a.id_no=b.id_no

哪位高手解释一下2,就是那个update语句。
...全文
399 点赞 收藏 6
写回复
6 条回复
切换为时间正序
当前发帖距今超过3年,不再开放新的回复
发表回复
rtsnd123 2015-08-20
感谢Tiger_Zhao,这下懂了。
回复
Tiger_Zhao 2015-08-17
[Quote=引用 2 楼 rtsnd123 的回复:]申明的三个变量不是还没赋值吗?怎么就可以有值判断呢?[/Quote]
第2段的UPDATE语句会针对每一行记录都执行一次四个表达式的运算。
第一行时:
  表达式1:@date2、@date1都是NULL,走 ELSE,所以 @date=in_date='2003-9-1 14:42:02'
  表达式2:@date1=in_date='2003-9-1 14:42:02'
  表达式3:@date2=@date='2003-9-1 14:42:02'
  表达式4:in_date=@date='2003-9-1 14:42:02'不变
后面的行@date2、@date1都有值了,就可以比较了。
回复
这个语句: update # set @date=case when @date2>=in_date or @date1=in_date then dateadd(s,1,@date2) else in_date end, @date1=in_date,@date2=@date,in_date=@date 就是用在update中,用来实现数据转换的,先通过值判断,计算出值放到@date里,然后把列in_date放到@date1,把@date保存到@date2,最后把刚才计算出来的值@date放到in_date里。 对于每条记录,都会有这么一个过程
回复
wangzhpwang 2015-08-14
能否改成这样,首先我们select 一下
SELECT  a.id_no ,
DATEADD(SECOND,
ROW_NUMBER() OVER ( PARTITION BY in_date ORDER BY id_no )
+ RANK() OVER ( ORDER BY in_date ) - 2, a.in_date) AS in_date
FROM a;

结果:

updated:
UPDATE t1
SET t1.in_date = t2.in_date
FROM a t1
INNER JOIN (
SELECT a.id_no,DATEADD(
SECOND,
ROW_NUMBER() OVER(PARTITION BY in_date ORDER BY id_no)
+ RANK() OVER(ORDER BY in_date) - 2,
a.in_date
) AS in_date
FROM a
)t2
ON t1.id_no = t2.id_no
GO
SELECT * FROM a

结果:

喝了点酒,不对之外请指正。
回复
wangzhpwang 2015-08-14
借用rwo_number函数加partition by 加order by 然后dateadd一秒
回复
rtsnd123 2015-08-14
感谢阳泉酒家小当家的答复,不过,我还是有疑问,“先通过值判断,计算出值放到@date里”,这句: declare @date1 datetime,@date2 datetime,@date datetime 申明的三个变量不是还没赋值吗?怎么就可以有值判断呢? 是不是语句先执行@date1=in_date,@date2=@date进行赋值呢?
回复
相关推荐
发帖
疑难问题
创建于2007-09-28

2.1w+

社区成员

MS-SQL Server 疑难问题
申请成为版主
帖子事件
创建了帖子
2015-08-14 11:03
社区公告
暂无公告