使用另一个列中的值更新一列,基于另一个公共列

时间:2014-05-14 15:26:42

标签: sql sql-server-2008

我有一个大的(300万行)交易数据表,因此可以简化:

ID  File        DOB
--------------------------
1   File1       01/01/1900
2   File1       03/10/1978
3   File1       03/10/1978
4   File2       15/07/1997
5   File2       01/01/1900
6   File2       15/07/1997

在某些情况下,没有日期。我想更新日期字段,以便它与具有日期的文件的其他记录相同。所以记录1的DOB将变成03/10/1978,因为该文件的记录2和3具有该日期。同样,记录5将成为15/07/1997。

实现这一目标的最有效方法是什么?

感谢。

3 个答案:

答案 0 :(得分:0)

我不知道最有效的方法,但我可以想到一个解决方案......使用以下查询创建临时表。虽然我不确定sqlserver 2008的确切关键字,但这可能有用,或者您可能需要更改关键字,如to_date及其格式。

创建表new_table为(  选择文件,min(DOB)为default_date,max(DOB)为fixed_date,来自three_million_table group by file min(dob)= to_Date(' 01/01/1900',' dd / mm / yyyy'))

所以你的新桌子会有 列标题:file,default_date,fixed_date
值:File1,01 / 01 / 1950,03 / 10/1978

现在在three_million_table上运行更新可能不明智,但是如果你认为它没问题那么:

更新T1 SET T1.DOB = T2.fixed_date 来自three_million_table T1 INNER JOIN new_table T2     ON T1.file = T2.file

答案 1 :(得分:0)

假设您的表名为“文件”,那么这将起作用:

UPDATE f1 SET f1.DOB=f2.MaxDOB
  FROM files f1
  JOIN (SELECT File, MAX(DOB) AS MaxDOB FROM files GROUP BY File) f2 ON
    f2.File=f1.File;

就性能而言,它可能不会比这更有效,但你确实需要确保(File,DOB)列集上有一个索引。 300万条记录很多,而且这个查询也会更新不需要它的记录,但过滤这些记录需要更复杂的连接。无论如何......你最好检查一下查询计划。

答案 2 :(得分:0)

希望这有帮助......拥有300万条记录肯定会通过扫描每条记录来更新表格

;WITH testCTE ([name],dobir,number)
     AS (SELECT [File],DOB, ROW_NUMBER() OVER (PARTITION BY [FILE],DOB
      ORDER BY ( SELECT 0)) RowNumber                                    
         FROM   test)
UPDATE TEST
SET DOB = tcte.dobir
FROM testCTE as tcte
LEFT JOIN TEST t on tcte.name = t.[FILE]
WHERE tcte.number > 1 and [FILE] = tcte.[name]

sql fiddle