我有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分,如果解决可以另开贴给分,现在就卡在这里了

解决方案 »

  1.   

    Update data set name=t.name 
    From data d cross apply (select top 1 name from person p where p.id=d.id) t 
      

  2.   

    按照所说的,如果person里同一个id有2个名字那就用第一条记录的name来更新
    person表是记录表,记录每一次姓名的变更;data表是直接使用的当前姓名
    实际业务中应该是data表数据不完整,想从person表更新过去
    这个操作其实只是操作一次,也就是将data表初始化,这个过程稍微慢一些无所谓的吧除非说整个程序每次更改姓名时没控制好,只修改了person表而没有修改data表——如果真是这样就是程序缺陷,改改程序避免两个表不同步。
      

  3.   

    谢谢,但是我用的不是sql server, 请问有通用的解决方法吗?
      

  4.   

    现在的问题是不能改表结构和逻辑,我们要在别的数据库上测试性能和Oracle比较,所以这个还是很重要的
    我是简化了一下问题,其实Data表是业务表,里面每天都要根据person来更新name, 这个操作经常做,所以跑一个月数据下来这个地方就很慢了
      

  5.   


    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'
      

  6.   

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

  7.   

    SAP的新的数据库,没有row_number这个玩意,所以很烦。
      

  8.   


    update Data set name = (select name from person UP TO 1 ROWS where person.id = Data.id ORDER BY person.name ) where date = '2013-01-23'