更新具有特定顺序的多个表

时间:2011-07-14 21:13:25

标签: sql sql-server sql-server-2005

好吧,也许是一个棘手的问题,但我知道这可能发生在我们中的一些人身上。我会尽量缩短它。

我有4个表,1个父表和3个子表。 (对于这个例子,它们具有相同的列,在我的实际情况中,它们没有)。像这样。

(4个表中的所有列都是整数)

PARENT                   
ID  POSITION             
1   1
2   1
3   1
4   1

CHILD1
IDPARENT, POSITION
1            2
1            3
1            4
1            6
2            3
2            4
3            2
3            5

CHILD2
IDPARENT, POSITION
1            5
1            7
2            2
3            3

CHILD3
IDPARENT, POSITION
4            2
4            3
3            6

所有表都有一个名为position的列,其中包含以下规则:

  1. 表PARENT始终具有position = 1
  2. 位置编号是每个父项的连续符号,无法在所有表格中重复。 (即父母1,孩子在child1,child2和child3,但是这个位置是连续的1,2,3,4,5,6,7,它不会在它们之间重复)
  3. 在同一张表中连续不能连续(即父亲1在子1中的位置为2 3 4 6,但5和7在子2中)。
  4. 所有表格中的父母可以而且不能生孩子(可能同时在child1和child3中,或者只有child2或没有子女)。
  5. 这些表是静态的,它始终是父项和3个子项。
  6. 我已经写了一个查询,以获得他们各自的孩子和位置的idparent。

    SELECT C.IDPARENT,  '1' AS CHILD, c.POSITION
    FROM  Child1 c
    UNION ALL
    SELECT C.IDPARENT,  '2' AS CHILD, c.POSITION
    FROM Child2 c
    UNION ALL
    SELECT C.IDPARENT,  '3' AS CHILD, c.POSITION
    FROM Child3 c
    UNION ALL 
    SELECT P.ID,  '0' AS CHILD,  P.POSITION
    FROM PARENT P
    ORDER BY IDPARENT, POSITION, CHILD
    

    它使用上述信息获得此输出。

    IDPARENT CHILD POSITION
        1   0   1
        1   1   2
        1   1   3
        1   1   4
        1   2   5
        1   1   6
        1   2   7
        2   0   1
        2   2   2
        2   1   3
        2   1   4
        3   0   1
        3   1   2
        3   2   3
        3   1   5
        3   3   6
        4   0   1
        4   3   2
        4   3   3
    

    正如您所看到的,信息得到了正确的输出,这就是我想要的。但这里有糟糕的记录

    3   2   3
    3   1   5
    

    它从3跳到5而不是4,因为有时在表中这些记录会被外部Web应用程序删除。

    所有这一切之后,这就是我的问题,是指这个问题的主题。

    如何以正确的顺序对所有这些表进行大量更新,记录如

      3   2   3
      3   1   5
      3   3   6
    

    转换为

     3   2   3
     3   1   4
     3   3   5
    

    注意:在我的例子中,我只做了一个糟糕的记录。在我的实际案例中,我得到了很多。

    到目前为止,我已经编写了该查询,这是我想要更新的数据,但我知道你不能一个接一个地更新大量表,但我不知道如果我只是用连续的顺序更新它们可以及时更新一个表。因为当下一个查询运行以更新下一个表时,它现在将具有不同的数据。

    感谢大家提前阅读这个长期问题并提供帮助。

1 个答案:

答案 0 :(得分:1)

;with cte as
(
  SELECT C.IDPARENT, c.POSITION
  FROM  Child1 c
  UNION ALL
  SELECT C.IDPARENT, c.POSITION
  FROM Child2 c
  UNION ALL
  SELECT C.IDPARENT, c.POSITION
  FROM Child3 c
  UNION ALL 
  SELECT P.ID, P.POSITION
  FROM PARENT P
)
select C.*, row_number() over(partition by IDPARENT order by POSITION) as rn
into #tmp
from cte as C

update C
  set Position = T.rn
from Child1 as C
  inner join #tmp as T
    on C.IDParent = T.IDParent and
       C.Position = T.Position

update C
  set Position = T.rn
from Child2 as C
  inner join #tmp as T
    on C.IDParent = T.IDParent and
       C.Position = T.Position

update C
  set Position = T.rn
from Child3 as C
  inner join #tmp as T
    on C.IDParent = T.IDParent and
       C.Position = T.Position

drop table #tmp

以上是您的查询。 Here您可以尝试使用表变量中的示例数据。插入语法适用于SQL Server 2008.