【问题标题】:Set One Column Equal to Another In Different Tables在不同的表中设置一列等于另一列
【发布时间】:2015-07-31 19:36:28
【问题描述】:

我对 SQL 还很陌生,我正在尝试创建一个 SQL 命令来检查某个表中的某个值是否等于某个值,然后更新另一个表中某个值的值。我在网上寻找过解决方案,但我还不够好,无法确定我所看到的是否可以用来完成我想要完成的事情。

以下是我正在使用的表和列的实际名称:

  • 项目(使用“ID”)
    • SaleType(整数,非空)
  • nitroasl_pamtable(使用“ItemID”)
    • PAM_SpecialOffer(位,非空)

两个表中产品之间共享的“ID”如下: - “项目”表中的“ID”列 - “nitroasl_pamtable”表中的“ItemID”列

我需要做的是遍历“Item”表并找到“SaleType”等于“1”的所有产品 - 然后通过将“PAM_SpecialOffer”设置为“1”来更新“nitroasl_pamtable”中的这些 ID。

以下是否能够做我想做的事(顺便说一句,这是一个非常粗略的猜测)?

UPDATE nitroasl_pamtable
SET PAM_SpecialOffer = SaleType
FROM Item
INNER JOIN nitroasl_pamtable
ON ID = ItemID
WHERE SaleType = 1

我希望以上内容是有道理的,因为我发现它有点难以用语言表达,但简而言之,我正在尝试将所有带有“SaleType=1”的产品标记为“PAM_SpecialOffer=1”两个不同的表,分别使用“ID”和“ItemID”。

更新

因此,以下内容为我提供了我想要更改的集合的列表。 ID 完全匹配,等等。现在我如何UPDATE PAM_SpecialOffer 列带有“1”(如何更改以下代码来执行此操作)?

SELECT i.ID, i.SaleType, i.SaleStartDate, i.SaleEndDate, i.ItemLookupCode, n.ItemID, n.PAM_SpecialOffer
FROM Item AS i
JOIN nitroasl_pamtable AS n
ON i.ID = n.ItemID
WHERE i.SaleType = 1
and (i.SaleStartDate > '2015-01-01' or i.SaleStartDate = '1899-12-31')
and i.SaleEndDate > getdate();

【问题讨论】:

  • 看起来它可能会起作用。当你尝试它时会发生什么?您可能需要为要更新的表设置别名。您绝对应该在连接条件中使用 TableName.ColumnName,而不是像现在这样使用 ColumnName。
  • 我会为这些表加上别名以避免歧义,但是是的,您走在正确的轨道上。
  • 我不知道 SQL 中的别名是什么。我将不得不查找它们......我也刚刚意识到我需要加入额外的逻辑。我需要检查Item 中的SaleStartDateSaleEndDate 值。我的头好痛……
  • 我如何“预览”这些更改以确保命令在运行之前有效?
  • BEGIN TRANS "UPDATE 语句" "SELECT 语句" ROLLBACK

标签: sql sql-server-2008 sql-update


【解决方案1】:

这就是我最终的结果。我确实需要用PAM_SpecialOffer = NULL 标记所有未收到PAM_SpecialOffer = 1 更新的产品,但这应该很容易!

UPDATE n
SET n.PAM_SpecialOffer = 1
FROM Item AS i
JOIN nitroasl_pamtable AS n
ON i.ID = n.ItemID
WHERE i.SaleType = 1
and (i.SaleStartDate > '2015-01-01' or i.SaleStartDate = '1899-12-31')
and i.SaleEndDate > getdate();

更新 - 最终修订版

所以我对查询进行了一些额外的修改。我确信有更好的方法来写这个,但这是我能做的最好的清理无效的 'PAM_SpecialOffer = 1' 行。使用我们的数据库备份进行测试-效果很好!我将把它设置为在我们的数据库上每隔几分钟运行一次。

/* Mark appropriate Sale items as 'PAM_SpecialOffer = 1' */

UPDATE n
SET n.PAM_SpecialOffer = 1
FROM Item AS i
JOIN nitroasl_pamtable AS n
ON i.ID = n.ItemID
WHERE i.SaleType >= 1
and (i.SaleStartDate >= '2015-04-01' or i.SaleStartDate = '1899-12-31')
and i.SaleEndDate >= getdate();


/* Cleanup 'PAM_SpecialOffer' */

UPDATE n
SET n.PAM_SpecialOffer = NULL
FROM Item AS i
JOIN nitroasl_pamtable AS n
ON i.ID = n.ItemID
WHERE i.SaleType < 1
or (i.SaleStartDate < '2015-04-01' and i.SaleStartDate <> '1899-12-31')
or i.SaleEndDate < getdate();

【讨论】:

    【解决方案2】:

    看来你的说法会奏效。但是,我会把它写成:

    UPDATE pt
    SET PAM_SpecialOffer = i.SaleType
    FROM nitroasl_pamtable pt INNER JOIN
         Item i
         ON i.ID = pt.ItemID
    WHERE i.SaleType = 1;
    

    ipt 是表别名,是表名的缩写。在某些情况下,它们是必要的。在这里,他们只是澄清了查询在做什么以及列的来源。

    通常,当我使用join 执行update 时,我会将正在更新的表放在连接列表的首位。

    【讨论】:

    • 这看起来与我添加附加逻辑之前的非常相似。非常感谢!这将完成我大部分需要的工作。 +1
    • 这确实回答了我原来的问题。谢谢!
    猜你喜欢
    • 2011-12-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-10
    • 1970-01-01
    • 1970-01-01
    • 2016-12-01
    • 1970-01-01
    相关资源
    最近更新 更多