【问题标题】:Updating row of table Using data from multiple columns of another table使用另一个表的多列中的数据更新表的行
【发布时间】:2009-11-07 19:48:14
【问题描述】:

我有下表,我想使用下面给出的另一个表进行更新。alt text http://img94.imageshack.us/img94/4602/leisureoriginal.png

我想根据 ProductId 使用下表更新上述给定表的 Null 值。 alt text http://img264.imageshack.us/img264/512/datatable2.png

更新后的表格应该是这样的。 alt text http://img690.imageshack.us/img690/9585/updatedtable.png

我在这些表中提到了 ProductId 只是举例。我不知道确切的 ProductId。它可以是任何 ProductId。

我提前知道第二张表中的 FieldId 和 FieldValue。

我可以在一个 UPDATE 语句中为所有列执行此操作吗?

【问题讨论】:

  • 能否列出源表和目标表的所有列名
  • 列名在标题中,在图像中。源表是第二个,目标表是第一个。

标签: sql sql-server tsql


【解决方案1】:

在 SQL Server 中,PIVOT 关键字将行转换为列。我们需要两个 PIVOT,一个用于 FieldId,一个用于 FieldValue。 ;WITH 关键字(前面有一个分号以将其与不相关的 WITH ROLLUP 命令区分开来)允许我们使用创建“临时视图”,我们稍后会在 UPDATE 语句中使用。

;WITH FieldIds AS (SELECT * FROM (SELECT ProductId, FieldId FROM ProductFields) A
                   PIVOT (MAX(FieldId) FOR FieldId IN ([50], [55], [60])) AS B),
      FieldValues AS (SELECT * FROM ProductFields
                      PIVOT (MAX(FieldValue) FOR FieldId IN ([50], [55], [60])) AS C)
UPDATE Products
SET
    RatingId = FieldIds.[50], 
    Rating = FieldValues.[50],
    LeisureId = FieldIds.[55],
    Leisure = FieldValues.[55], 
    SpaId = FieldIds.[60],
    Spa = FieldValues.[60]
FROM Products
INNER JOIN FieldIds ON FieldIds.ProductId = Products.ProductId
INNER JOIN FieldValues ON FieldValues.ProductId = Products.ProductId

【讨论】:

    【解决方案2】:

    在 SQL Server 中,UPDATE 语句允许带有 JOINS 的 FROM 子句。例如,此查询将更新 Rating 字段:

    UPDATE      p
    SET         p.Rating = pf.FieldValue
    FROM        Products p
    INNER JOIN  ProductField pf
    ON          pf.ProductId = p.ProductId
    WHERE       pf.FieldId = 50
    

    您可以将此查询复制到其他字段。也可以在查询中更新更多字段,但在这种情况下似乎没有必要。

    【讨论】:

      【解决方案3】:

      您首先需要转换第二个表,使其每个 ProductID 仅包含一行。

      SELECT t1.ProductID, t1.FieldID AS RatingID, t1.FieldValue AS Rating, 
             t2.FieldID AS LeisureID, t2.FieldValue AS Leisure, etc.
      FROM SecondTable t1
      LEFT OUTER JOIN SecondTable t2 
             ON t1.ProductID = t2.ProductID 
             AND t2.FieldValue = 55
      LEFT OUTER JOIN SecondTable t3 
             ON t1.ProductID = t3.ProductID 
             AND t3.FieldValue = 60
      WHERE t1.FieldValue = 50
      

      然后您可以在一个更新查询中从该表更新第一个表中的所有列。请注意,您可以将上述设置为第二个表的视图,以便以后更容易使用。 (我们暂时称它为 SecondTableView;顺便说一下,它现在具有第一个表的确切形式)。

      UPDATE FirstTable 
      SET RatingID = t1.RatingID, Rating = t1.Rating, etc.
      FROM SecondTableView t1
      WHERE FirstTable.ProductID = t1.ProductID
      

      这种方法的问题是,您必须提前知道每个产品的所有可能字段,但由于表架构已修复,这几乎是必需的。

      【讨论】:

        【解决方案4】:

        可能是这样的:

        Update T1
        Set T1.RatingID = T2.FieldID,
        T1.Rating = T2.FieldValue
        From Table1 T1
        Inner JOin Table2 T2
        On T1.ProductID = T2.ProductID
        Where T2.FieldID = 50
        

        要一次编辑所有列,您需要使用子查询:

        Update T1
        Set T1.RatingID = (Select T2.FieldID
                           From Table2 T2
                   Where T2.FieldID = 50
                    And T2.ProductID = T1.ProductID)
        From Table1 T1
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2021-01-08
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-04-02
          • 1970-01-01
          相关资源
          最近更新 更多