2011-04-29 65 views
0

我已经有了一个表中的一行:匹配一个表的每一行与另一个表

TABLE_A 
----------- 
Sc Cl Pr Br 
----------- 
1 1 1 NULL 
2 1 1 NULL 
1 2 2 NULL 
2 2 2 NULL 

(SC,氯,PR)是候选键

为了赋值字段Br(认为这是理所当然的,它不能改变)我将这些行插入到带有Br字段的3个字段(Br,Cl,Pr)的TABLE_B中,字段Br自动递增(为了使事情更简单,假设TABLE_B为空,TABLE_A仅包含上述行)。所以我做这样的事情

INSERT INTO TABLE_B (Cl, Pr) SELECT Cl, Pr FROM TABLE_A 

现在我要指派自动生成TABLE_B.Br到TABLE_A.Br以这样的方式

TABLE_B.Cl = TABLE_A.Cl AND TABLE_B.Pr = TABLE_A.Pr

和TABLE_A T1的每两行,T2是

t1.Cl = t2.Cl AND t1.Pr = t2.Pr AND t1.Sc <> t2.Sc => t1.Br <> t2.Br 

PS 1:我希望这不是太混乱:(

PS 2:我找到的唯一快速简单的解决方案是在TABLE_B(Sc)中添加一个字段,然后表之间的简单连接就可以完成这项工作。但添加一列不是一个选项。

+0

这可能是太混乱...也许这将有助于看到什么生成的表格数据一旦完成就会生成? – ShaneBlake 2011-04-29 21:17:24

+0

您使用的是哪个版本的SQL-Server? – 2011-04-29 22:12:38

+0

看看这里。 http://stackoverflow.com/questions/5830229/copy-each-identity-of-inserted-records/5831028#5831028。另一个人问几乎同样的问题。我真的很想知道为什么这些表的设计是这样的。根本没有任何意义。 – 2011-04-29 22:17:50

回答

0

这似乎更像是一个谜不是一个问题。难道你不能删除列Br并再次添加它作为自动递增?

总之,这里的使用ROW_NUMBER()PARTITION的解决方案:

UPDATE A 
SET A.Br = B.Br 
FROM 
    (SELECT Cl 
      , Pr 
      , ROW_NUMBER() 
       OVER(PARTITION BY Cl, Pr ORDER BY Sc) 
      AS rowNo 
      , Br 
     FROM TABLE_A 
    ) AS A 
    JOIN 
    (SELECT Cl 
      , Pr 
      , ROW_NUMBER() 
       OVER(PARTITION BY Cl, Pr ORDER BY Br) 
      AS rowNo 
      , Br 
     FROM TABLE_B 
    ) AS B 
    ON A.Cl = B.Cl 
    AND A.Pr = B.Pr 
    AND A.rowNo = B.rowNo; 

关于第二个想法,你并不真正需要TABLE_B。您可以指定自动值与到现场Br

UPDATE A 
SET A.Br = A.rowNo 
FROM 
    (SELECT ROW_NUMBER() 
       OVER(ORDER BY Cl, Pr, Sc) 
      AS rowNo 
      , Br 
     FROM TABLE_A 
    ) AS A; 
+0

总而言之,我想要创建第三个字段“rowNo”,以便(Cl,Pr,rowNow)将是唯一的。第二种解决方案仅适用于(Sc,Cl,Pr)是唯一的(在定义的问题中),但在实际问题中TABLE_A是Sc,Cl,Pr上的独立选择的结果,其中Br是NULL,几次插入新值后) – Blim 2011-04-30 11:55:19

0

如果你只得到了两个值钪然后尝试这两个语句:

Update TABLE_A a set br = (select min(br) // select lowest br values 
          from TABLE_B b 
          where a.cl = b.cl 
           and a.pr = b.pr) 
where a.sc = (select min(sc)    // updating lower sc values 
        from TABLE_A c 
       where a.cl = c.cl 
        and a.pr = c.pr) 

Update TABLE_A a set br = (select max(br) // select highest br values 
           from TABLE_B b 
          where a.cl = b.cl 
           and a.pr = b.pr) 
where a.sc = (select max(sc) 
        from TABLE_A c 
       where a.cl = c.cl 
        and a.pr = c.pr)   // update highest sc values 
+0

Nope Sc可以有多个值。 TABLE_A是更复杂表格的抽象示例。我在想的是使用临时表来保存Cl和Pr上连接的结果,然后找到一种方法来消除额外的行,或者用where子句消除这些额外的行,但无法想到任何方式来做到这一点。 – Blim 2011-04-29 21:41:55

0

如果使用SQL Server 2008中您可以使用mergeoutput

declare @T table(Sc int, Cl int, Pr int, Br int); 

merge TABLE_B as T 
using TABLE_A as S 
on 1=0 
when not matched then 
    insert(Cl, Pr) values(S.Cl, S.Br) 
output S.Sc, S.Cl, S.Pr, inserted.Br into @T; 

update A 
    set Br = T.Br 
from TABLE_A as A 
    inner join @T as T 
    on A.Sc = T.Sc and 
     A.Cl = T.Cl and 
     A.Pr = T.Pr; 
相关问题