MS SQL 更新具有多个条件的表

发布于 2024-11-16 23:45:08 字数 914 浏览 0 评论 0原文

阅读这个网站寻找答案已经有一段时间了,现在问我的第一个问题!

我正在使用 SQL Server,

我有两个表:ABCABC_Temp

内容首先插入 ABC_Temp,然后再进入 ABC。 表 ABCABC_Temp 具有相同的列,但 ABC_Temp 有一个名为 LastUpdatedDate 的额外列,其中包含上次更新的日期。由于 ABC_Temp 可以有 1 条以上的相同记录,因此它具有由项目编号和上次更新日期组成的复合键。

这些列是: 项目编号 |价格| Qty 和 ABC_Temp 有一个额外的列:LastUpdatedDate

我想创建一个遵循以下条件的语句:

  1. 检查 ABC 的每个属性是否与 的值不同>ABC_Temp 对于具有相同键的记录,如果是则进行更新(即使只有一个属性不同,其他所有属性也可以更新)
  2. 如果记录相同,则仅更新需要更改的记录,那么就不会更新了。
  3. 由于一项在 ABC_Temp 中可以有多个记录,我只想将最新更新的记录更新为 ABC

我目前正在使用 2005(我认为,不在工作中)那一刻)。

这将位于一个存储过程中,并在 VBscript 计划任务中调用。所以我相信这是一次性的事情。另外,我并没有尝试同步这两个表,因为 ABC_Temp 的内容仅包含通过 BCP 从文本文件批量插入的新记录。为了上下文的缘故,这将与检查记录是否存在的插入存储过程结合使用。

Been reading this site for answers for quite a while and now asking my first question!

I'm using SQL Server

I have two tables, ABC and ABC_Temp.

The contents are inserted into the ABC_Temp first before making its way to ABC.
Table ABC and ABC_Temp have the same columns, except that ABC_Temp has an extra column called LastUpdatedDate, which contains the date of the last update. Because ABC_Temp can have more than 1 of the same record, it has a composite key of the item number and the last updated date.

The columns are: ItemNo | Price | Qty and ABC_Temp has an extra column: LastUpdatedDate

I want to create a statement that follows the following conditions:

  1. Check if each of the attributes of ABC differ from the value of ABC_Temp for records with the same key, if so then do the update (Even if only one attribute is different, all other attributes can be updated as well)
  2. Only update those that need changes, if the record is the same, then it would not update.
  3. Since an item can have more than one record in ABC_Temp I only want the latest updated one to be updated to ABC

I am currently using 2005 (I think, not at work at the moment).

This will be in a stored procedure and is called inside the VBscript scheduled task. So I believe it is a once time thing. Also I'm not trying to sync the two tables, as the contents of ABC_Temp would only contain new records bulk inserted from a text file through BCP. For the sake of context, this will be used with in conjunction with an insert stored proc that checks if records exist.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

水波映月 2024-11-23 23:45:08
UPDATE
    ABC
SET
    price = T1.price,
    qty = T1.qty
FROM
    ABC
INNER JOIN ABC_Temp T1 ON
    T1.item_no = ABC.item_no
LEFT OUTER JOIN ABC_Temp T2 ON
    T2.item_no = T1.item_no AND
    T2.last_updated_date > T1.last_updated_date
WHERE
    T2.item_no IS NULL AND
    (
        T1.price <> ABC.price OR
        T1.qty <> ABC.qty
    )

如果 priceqty 列中可能存在 NULL 值,那么您需要考虑到这一点。在这种情况下,我可能会将不等式语句更改为如下所示:

COALESCE(T1.price, -1) <> COALESCE(ABC.price, -1)

假设 -1 不是数据中的有效值,因此您不必担心它实际出现在那里。

另外,ABC_Temp 真的是一个临时表,只是加载了足够长的时间才能将值放入 ABC 中吗?如果没有,那么您将在多个位置存储重复的数据,这是一个坏主意。第一个问题是现在你需要这些类型的更新场景。您可能会遇到其他问题,例如数据不一致等。

UPDATE
    ABC
SET
    price = T1.price,
    qty = T1.qty
FROM
    ABC
INNER JOIN ABC_Temp T1 ON
    T1.item_no = ABC.item_no
LEFT OUTER JOIN ABC_Temp T2 ON
    T2.item_no = T1.item_no AND
    T2.last_updated_date > T1.last_updated_date
WHERE
    T2.item_no IS NULL AND
    (
        T1.price <> ABC.price OR
        T1.qty <> ABC.qty
    )

If NULL values are possible in the price or qty columns then you will need to account for that. In this case I would probably change the inequality statements to look like this:

COALESCE(T1.price, -1) <> COALESCE(ABC.price, -1)

This assumes that -1 is not a valid value in the data, so you don't have to worry about it actually appearing there.

Also, is ABC_Temp really a temporary table that's just loaded long enough to get the values into ABC? If not then you are storing duplicate data in multiple places, which is a bad idea. The first problem is that now you need these kinds of update scenarios. There are other issues that you might run into, such as inconsistencies in the data, etc.

滴情不沾 2024-11-23 23:45:08

您可以使用cross apply 使用相同的键来查找ABC_Temp 中的最后一行。使用 where 子句过滤掉没有差异的行:

update  abc
set     col1 = latest.col1
,       col2 = latest.col2
,       col3 = latest.col3
from    ABC abc
cross apply
        (
        select  top 1 *
        from    ABC_Temp tmp
        where   abc.key = tmp.key
        order by
                tmp.LastUpdatedDate desc
        ) latest
where   abc.col1 <> latest.col1
        or (abc.col2 <> latest.col2
            or (abc.col1 is null and latest.col2 is not null)
            or (abc.col1 is not null and latest.col2 is null))
        or abc.col3 <> latest.col3

在示例中,只有 col2 可为空。由于 null <> 1 不正确,您必须使用 is null 语法检查涉及 null 的差异。

You could use cross apply to seek the last row in ABC_Temp with the same key. Use a where clause to filter out rows with no differences:

update  abc
set     col1 = latest.col1
,       col2 = latest.col2
,       col3 = latest.col3
from    ABC abc
cross apply
        (
        select  top 1 *
        from    ABC_Temp tmp
        where   abc.key = tmp.key
        order by
                tmp.LastUpdatedDate desc
        ) latest
where   abc.col1 <> latest.col1
        or (abc.col2 <> latest.col2
            or (abc.col1 is null and latest.col2 is not null)
            or (abc.col1 is not null and latest.col2 is null))
        or abc.col3 <> latest.col3

In the example, only col2 is nullable. Since null <> 1 is not true, you have to check differences involving null using the is null syntax.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文