更新期间强制唯一值,没有良好的连接键

时间:2015-09-10 19:56:56

标签: tsql

我有一张桌子" MyTable"有3列:

  • 文件路径
  • 文件名
  • 状态

我的表格行示例:

FilePath | FileName | Status
c:\temp  | Null     | 30
c:\temp  | Null     | 30
c:\temp  | Null     | 30
c:\temp  | Null     | 30
c:\temp  | a.csv    | 40
c:\temp  | b.csv    | 40
c:\temp  | c.csv    | 40
c:\temp  | d.csv    | 40

我想更新FileName为null的行,其中包含FileName具有值的行。

现在,以下查询将更新具有相同值的空值。

我需要强制更新在更新期间每行选择一个唯一值

UPDATE  t1
SET t1.FileName = t2.FileName
FROM MyTable t1
JOIN MyTable t2 ON t1.FilePath = t2.FilePath

当前更新将提供以下结果:

FilePath | FileName | Status
c:\temp  | a.csv    | 30
c:\temp  | a.csv    | 30
c:\temp  | a.csv    | 30
c:\temp  | a.csv    | 30
c:\temp  | a.csv    | 40
c:\temp  | b.csv    | 40
c:\temp  | c.csv    | 40
c:\temp  | d.csv    | 40

我需要的是:

FilePath | FileName | Status
c:\temp  | a.csv    | 30
c:\temp  | b.csv    | 30
c:\temp  | c.csv    | 30
c:\temp  | d.csv    | 30
c:\temp  | a.csv    | 40
c:\temp  | b.csv    | 40
c:\temp  | c.csv    | 40
c:\temp  | d.csv    | 40

1 个答案:

答案 0 :(得分:1)

假设您正在使用相当现代的SQL Server版本,并希望FileName模式重新开始,并根据需要为每个具有NULL FileName值的状态重复:

-- Sample data.
declare @MyTable as Table ( Id Int Identity, FilePath VarChar(16), FileName VarChar(16), Status Int );
insert into @MyTable ( FilePath, FileName, Status ) values
  ( 'c:\temp', null, 30 ),
  ( 'c:\temp', null, 30 ),
  ( 'c:\temp', null, 30 ),
  ( 'c:\temp', null, 30 ),
  ( 'c:\temp', 'a.csv', 40 ),
  ( 'c:\temp', 'b.csv', 40 ),
  ( 'c:\temp', 'c.csv', 40 ),
  ( 'c:\temp', 'd.csv', 40 ),
  ( 'c:\temp', null, 50 ),
  ( 'c:\temp', null, 60 ),
  ( 'c:\temp', null, 60 ),
  ( 'c:\temp', null, 60 ),
  ( 'c:\temp', null, 60 ),
  ( 'c:\temp', null, 60 ),
  ( 'c:\temp', null, 60 ),
  ( 'c:\temp', null, 60 );
select * from @MyTable;

-- Update the   null   values.
with
  FileNames as (
    select FileName, Row_Number() over ( order by FileName ) - 1 as RN
      from @MyTable
      where FileName is not NULL ),
  NullNames as (
    select Id, Row_Number() over ( partition by Status order by FileName ) - 1 as RN
      from @MyTable
      where FileName is NULL )
  update MT
    set FileName = FN.FileName
    from @MyTable as MT inner join
      NullNames as NN on NN.Id = MT.Id inner join
      FileNames as FN on FN.RN = NN.RN % ( select count(42) from FileNames );
select * from @MyTable;