日期:2014-05-17  浏览次数:20618 次

改写rownum的问题
我有2个表,一个是Data, 里面有personId, name, date等字段,这个表比较小,最多几千条记录,另外一个是person表,里面有id, name等,这个表很大,有上千万条记录,并且有少量id重复,其实就是一个身份证号对应2个名字(因为有人改过名字),现在有个需求是用person表里的name来更新Data表里的名字,Oracle的语句大概如下:
update Data set name = (select name from person where person.id = personId and rownum = 1) where date = '2013-01-23'
这样就是如果person里同一个id有2个名字那就用第一条记录的name来更新。这个没有问题。现在我们有需求把他改成别的数据库语句来写,里面没有rownum这个关键字,我尝试用
update Data set name = (select top 1 name from person where person.id = Data.id ) where date = '2013-01-23'
来写,但是语法错误,说是相关子查询里不能有排序,所以现在想到的是用inner join:
update data set name = pname from data inner join (select min(name), id from person group by id) b on b.id = personId where date = '2013-01-23'
这个可以工作,但是很慢,因为group by的时候有上千万个分组,但实际要更新的数据只有几十条。所以不知道各位高手有没有这方面的经验,有什么简单的办法可以实现这个功能?谢谢!
一次只能给100分,如果解决可以另开贴给分,现在就卡在这里了。。。

------解决方案--------------------
Update data set name=t.name 
From data d cross apply (select top 1 name from person p where p.id=d.id) t 
------解决方案--------------------
按照所说的,如果person里同一个id有2个名字那就用第一条记录的name来更新
person表是记录表,记录每一次姓名的变更;data表是直接使用的当前姓名
实际业务中应该是data表数据不完整,想从person表更新过去
这个操作其实只是操作一次,也就是将data表初始化,这个过程稍微慢一些无所谓的吧

除非说整个程序每次更改姓名时没控制好,只修改了person表而没有修改data表——如果真是这样就是程序缺陷,改改程序避免两个表不同步。
------解决方案--------------------

UPDATE d 
SET name = p.person
FROM Data d INNER JOIN  (select top 1 id,name from person  order by id asc ) P
ON D.personId  = P.id
WHERE d.date = '2013-01-23'

------解决方案--------------------
请问"别的数据库"是什么数据库呢?
 Oracle里有rownum,
 SQL Server里有row_number(),
其他数据库也应该有相对应的函数或替代的方法的.
------解决方案--------------------