将一个表的每一行与另一个表的一行匹配

时间:2011-04-29 20:58:07

标签: sql sql-server

我有一张桌子:

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

(Sc,Cl,Pr)是候选键

为了给字段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

AND每两行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)中添加一个字段,然后表之间的简单连接就可以完成工作。但是添加列不是一种选择。

3 个答案:

答案 0 :(得分:0)

如果你只有Sc的两个值,那么试试这两个语句:

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

答案 1 :(得分: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;

答案 2 :(得分: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;