使用一对多 JOIN 进行更新(多列)

2024-01-25

我遇到了一个问题,我不确定这是否是预期的行为。我在网上搜索了答案,但我所能找到的只是关于最后更新的行以及查询后的值是多少。我知道在这种情况下不存在订单之类的东西,并且您无法提前确定其价值是多少。

但就我而言,我正在更新不同的列,因此覆盖以前的更新不是我关心的问题。

CREATE TABLE #original (id int, value1 int, value2 int)
INSERT INTO #original (id) VALUES (1), (2)

CREATE TABLE #temp (id int, name varchar(10), value int)
INSERT INTO #temp (id, name, value) VALUES (1, 'value1', 10), (1, 'value2', 11), (2, 'value1', 20), (2, 'value2', 21)

SELECT * FROM #original

id          value1      value2
----------- ----------- -----------
1           NULL        NULL
2           NULL        NULL

SELECT * FROM #temp

id          name       value
----------- ---------- -----------
1           value1     10
1           value2     11
2           value1     20
2           value2     21

UPDATE O SET 
    value1 = CASE WHEN T.name = 'value1' THEN T.value ELSE value1 END,
    value2 = CASE WHEN T.name = 'value2' THEN T.value ELSE value2 END
FROM
    #original O
        INNER JOIN #temp T ON T.id = O.id

SELECT * FROM #original

id          value1      value2
----------- ----------- -----------
1           10          NULL
2           20          NULL

我不明白为什么两者value2 are NULL.

SELECT
    O.id,
    CASE WHEN T.name = 'value1' THEN T.value ELSE value1 END AS value1,
    CASE WHEN T.name = 'value2' THEN T.value ELSE value2 END AS value2
FROM
    #original O
        INNER JOIN #temp T ON T.id = O.id

id          value1      value2
----------- ----------- -----------
1           10          NULL
1           NULL        11
2           20          NULL
2           NULL        21

运行上面的内容而不是更新,它看起来与我想象的完全一样,我认为这意味着“四个”更新,填充两者value1 and value2在两行中。

如果有人能向我解释这一点,我将非常感激。


这里的问题是你的假设:“但就我而言,我正在更新不同的列,因此覆盖以前的更新不是我关心的问题。” 最肯定的是is一个问题,因为最终,你的代码

value1 = CASE WHEN T.name = 'value1' THEN T.value ELSE value1 END,
value2 = CASE WHEN T.name = 'value2' THEN T.value ELSE value2 END

每行仅运行(或生效)一次。 SQL Server 不需要将同一行更新两次,并且通常会任意采用单行的值,其中之一是NULL.

文档指出 https://learn.microsoft.com/en-us/sql/t-sql/queries/update-transact-sql?view=sql-server-ver15#best-practices (我的大胆):

指定时要小心FROM子句提供更新操作的条件。结果UPDATE声明是不明确的如果该语句包含FROM未以这样一种方式指定的子句:对于更新的每个列出现只有一个值可用,即如果UPDATE声明不是确定性的。例如,在UPDATE在以下脚本中的语句中,表 1 中的两行均满足FROM中的条款UPDATE陈述;但未定义使用 Table1 中的哪一行来更新 Table2 中的行。

Only one row可能会被使用并完成一次更新,但您不能假设更新将按顺序发生。所以你需要确保你有一个single匹配您要更新的每一行。

因此你应该预先汇总你的价值观

UPDATE O SET 
    value1 = T.value1,
    value2 = T.value2
FROM
    #original O
INNER JOIN (
    SELECT
      id,
      MAX(CASE WHEN T.name = 'value1' THEN T.value END) value1,
      MAX(CASE WHEN T.name = 'value2' THEN T.value END) value2,
    FROM #temp T
    GROUP BY
      id
) T ON T.id = O.id;

你也可以使用CROSS APPLY或 CTE。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用一对多 JOIN 进行更新(多列) 的相关文章

  • 如何通过Object Id和Column Id查询表数据?

    有桌子Clients PK LastName Name Address 1 Vidal Arturo St 2 Lavezzi Ezequiel St 3 Cuadrado Guillermo St 我想得到 通过以下查询 我可以得到前四列
  • 数据结构的优化存储以实现快速查找和持久化

    Scenario 我有以下方法 public void AddItemSecurity int itemId int userIds public int GetValidItemIds int userId 最初我正在考虑表单上的存储 i
  • 仅从数据库获取我想要的数据但保留结构

    我正在尝试在 powerbi 上执行此操作 但我想这只是基本的 SQL 我想将我的数据导入到 powerBi 中 但使用一些 id 对其进行过滤 我们以这个例子为例 我与一些公司有数据库 表1 每个公司都有建筑物 表2 每个建筑物有员工 表
  • .NET:SqlDataReader.Close 或 .Dispose 导致超时过期异常

    当尝试在 SqlDataReader 上调用 Close 或 Dispose 时 我收到超时过期异常 如果您有到 SQL Server 的 DbConnection 您可以使用以下命令自行重现它 String CRLF r n String
  • 如何找到在SQL Server中注册的程序集?

    我在 SQL Server 中注册了一个程序集 CREATE ASSEMBLY CLRFunctions AUTHORIZATION dbo FROM 0x4D5A90000300000 WITH PERMISSION SET SAFE 我
  • 按小时拆分日期/时间数据并将日期/时间范围展开为行

    我正在尝试使用 SQL Server 将一系列日期 时间数据扩展为多行 例如 我的数据看起来像 Date StartTime EndTime EmployeeID ShiftType 10 1 2019 8 30 00AM 4 57 00P
  • Oracle:如何查找模式中上次更新(任何表)的时间戳?

    有一个Oracle数据库模式 数据很小 但仍然有10 15个表左右 它包含一种配置 路由表 有一个应用程序必须不时轮询此架构 不得使用通知 如果架构中没有数据更新 应用程序应使用其当前的内存版本 如果任何表有任何更新 应用程序应将所有表重新
  • 仅当变量不为空时 SQL 添加过滤器

    您好 我有疑问如下 SELECT route id ROUTE ID FROM route master NOLOCK WHERE route ou 2 AND route query l s query AND lang id 1 这里
  • sql server GO 相当于 oracle

    我正在为 Oracle 编写迁移脚本 我需要更改表结构 然后用数据填充它 我想先进行结构更改 然后再进行数据更改 在 SQL Server 中我会使用GO分离批次 是否有 SQL ServerGOOracle 中的等效命令 It s and
  • SSRS。如何在table1_Details_Group右侧创建新的行组?

    我正在使用 Microsoft Visual Studio 2013 创建报告 PROBLEM 如果我添加新的Row Group前面会自动添加table1 Details Group 问题 如何更改组的顺序或在右侧添加新组table1 De
  • SQL - 为每条记录调用存储过程

    我正在寻找一种方法来为 select 语句的每条记录调用存储过程 SELECT SomeIds SELECT spro Id FROM SomeTable as spro INNER JOIN Address addr ON addr Id
  • 案例陈述以确定我是否应该结合

    我目前想做某种条件联合 给出以下示例 SELECT age name FROM users UNION SELECT 25 AS age Betty AS name 假设我只想在 用户 计数 gt 2 时合并第二个语句 否则不合并两者 总之
  • 对具有许多索引的表进行缓慢的批量插入

    我尝试将数百万条记录插入到具有 20 多个索引的表中 在上次运行中 每 100 000 行花费了 4 个多小时 并且查询在 3 5 天后被取消 您对如何加快速度有什么建议吗 我怀疑是索引太多的原因 如果你也这么认为 如何在操作前自动删除索引
  • 在 C# 中将平面数据库结果集转换为分层对象集合

    我有一个数据库查询 它以平面格式返回分层数据 例如客户 订单和订单项目 只是一个例子 我的数据不同 如何将其转换为分层对象集合 即客户对象的集合 其中每个客户对象都有订单对象的集合 每个订单对象都有订单项目对象的集合 这只是循环遍历每个项目
  • 自动创建n列表

    我想在一行中将 236 个 int 值存储到 sql 中 现在我必须声明该表 但我不想输入 236 倍的列名 列名应该是 BYTE001 BYTE002 或其他前缀 如 BYTE B INT 可以自动生成ColumnNames吗 我尝试以下
  • PHP、PDO 和 SQLSRV 对一个 INSERT 语句执行多次

    我已经在 MySQL 和 Apache 服务器上使用 PDO 和 PHP 一段时间了 我最近的任务是将企业的旧 Web 应用程序转换为新设置 旧设置是标准 Linux Web 堆栈 Apache PHP MySQL Filezilla 新设
  • 在 SSIS 中使用合并任务的指南

    我有一个包含三个字段的表 其中一个是身份字段 我需要从具有其他两个字段的源中添加一些新记录 我正在使用SSIS 我认为我应该使用合并工具 因为其中一个源不在本地数据库中 但是 我对合并工具和正确的过程感到困惑 我有一个源 一个 Oracle
  • 在 Navicat Premium 中连接到 LocalDB 服务器

    Recently I installed LocalDb Serer on my laptop I am trying to establish a connection between Navicat and LocalDB server
  • 在 SQL Server SELECT 语句中使用 CASE 时消除 NULL

    我有一份大而混乱的报告要写 它连接了 5 个表 一个表中有一列用于多个不同的值 本质上是一个 标签 列 其中标签根据用户想要使用的各种元数据的类型以创造性的方式使用 因此 我对报告的查询返回 3 个几乎相同的行 仅 标签 列有所不同 例如
  • 临时表上没有外键限制? SQL Server 2008

    我知道临时表只会在 SQL Server 会话打开时存在 但为什么不能对它们进行外键限制呢 想象一下这样的场景 您创建从临时表到具体表的键的外键关系 外键关系的限制之一是您无法从临时表所依赖的键表中删除行 现在 通常当您创建外键关系时 您知

随机推荐

  • 确定与 perl 中的正则表达式匹配的部分

    我正在寻找正则表达式可能重叠的匹配的累积 最终目标是在结果子字符串中进行进一步搜索 我想跳过已经 累积 的匹配 同时避免使用substr 我可能是错误的避免substr 但是我为它写的条件是pos and a next if 不起作用 us
  • Docker ADD 与 VOLUME

    我正在学习 Docker 但我对何时何地使用 Docker 有疑问ADD and VOLUME 我认为这两者的作用如下 ADD 在构建时将文件复制到映像 该映像包含所有文件 因此您可以非常轻松地进行部署 另一方面 在开发中每次都需要构建看起
  • Firebase 的云功能 - 无法加载 URL:不存在“Access-Control-Allow-Origin”标头

    我有一个 Angular 2 应用程序 我通过 http 请求调用 Firebase 但是 每当我尝试运行该函数时 都会收到此错误 XMLHttpRequest cannot load https us central1
  • Hibernate 标准多选查询与连接

    下面是我的实体类 我使用条件生成器检索该实体 但我只需要获取id title and tags 问题 java Entity Table name QUESTION TITLE public class Question Id Column
  • beginAt、endAt 使用索引而不是优先级

    有没有办法将 beginAt 和 endAt 与索引而不是优先级一起使用 以便我可以用它进行客户端分页 我将 priority 分配给非空值进行排序 您可以使用 startAt endAt 的第二个参数来执行此操作 请注意 在对消息进行排序
  • 无法使用 robo3T 和 C# 从其他服务器连接到 MongoDB 副本集

    我已经安装了mongodb副本集 在文件中mongod conf已添加 BIND IP 如下 net port 27017 bindIp 127 0 0 1 100 0 192 68 当我使用robo3t连接 副本集 时键入错误 但是当连接
  • Oracle ODP.NET 连接字符串:数据源中有什么?

    这是 ODP NET 的 ConnectionStrings com 字符串 很棒 但是什么是数据源 数据源 TORCL 用户ID someUser 密码 son28dnn 是控制面板中的DSN吗 服务器名称 TNS 命名服务名称 Than
  • 如何从 OpenXML 中的名称或工作表 ID 获取 Worksheetpart?

    下面创建一个 XLSX 添加两个包含一些数据的工作表 然后 我希望能够稍后根据名称 或者最好是 ID 获取电子表格 以便我可以在稍后的时间点添加 修改工作表 我不知道如何再次获取下面代码不完整的工作表 Sub Main Using doc
  • 如何使用 Node.JS 进行请求 HTTP 摘要身份验证?

    我必须使用 Node JS 为 API 文档编写一些代码 但我在过去几天尝试了在网络上找到的所有解决方案 当然包括 Stack 但没有成功 我的 API 使用 HTTP Digest Auth 这就是问题所在 我能够连接 这不是什么大问题
  • 按 Cassandra 中的任何字段排序

    我正在研究 cassandra 作为我即将进行的项目的可能解决方案 我研究得越多 我就越常听到这样的说法 对创建表时未设置排序的字段进行排序是一个坏主意 是否可以对任何字段进行排序 如果对不在集群中的字段进行排序会对性能产生影响 那么性能影
  • 配置温莎城堡和通用

    这是我在 Global asax 中的代码 WindsorContainer container new WindsorContainer container Register Component For typeof IRepositor
  • Scrapy中不同start_url的不同解析函数

    Scrapy可以为每个start url设置不同的解析函数吗 这是一段伪代码 start urls http 111sssssssss com http 222sssssssssssss com http 333sssssssssss co
  • 如何计算 git 树哈希?

    对于 Nodejs 项目 我需要确定文件夹的哈希值来检查版本 实际上 我制作了一个脚本来测试我的代码 没有文件系统 直接使用 git api 进行测试 但它有一半的时间有效 A1 https api github com repos zes
  • MySQL 按特定 24 小时间隔进行分组

    我有一个 MySQL 表 每行都有时间戳值 我的目标是对金额列的值求和 并按自定义 24 小时间隔 每天 05 30 00 开始 进行分组 input timestamp amount 2015 01 19 08 30 12 4 2015
  • 如何在数学图中画三角形?

    如何在显示 X 轴和 Y 轴的数学图表中绘制三角形 要使用 ActionScript2 绘制形状 您可以使用moveTo and lineTo MovieClip 对象的方法 您可以指定线条颜色和粗细线条样式 或者使用以下方法制作实体形状开
  • 如何从 CMake 中隐藏 Visual Studio 中的目标

    我正在使用 CMake 生成 sln 我想使用 Google Test 并使用此类代码来添加新测试 add executable my test test my test cpp target link libraries my test
  • 在数组中查找本地分钟

    有没有一种简单的方法来确定值数组的局部最小值和最大值 例如 Element Value Note 1 1 2 3 3 5 4 6 5 7 max 5 5 6 4 min 7 6 8 9 9 10 max 10 8 11 7 12 5 min
  • 动态获取 Android 设备的供应商 ID

    我想要得到Vendor ID通过我的代码访问我的 Android 设备 我读过这个 http developer android com tools device html http developer android com tools
  • 为什么在 hashcode() 实现中选择 31 来进行乘法? [复制]

    这个问题在这里已经有答案了 可能的重复 为什么Java的String中的hashCode 使用31作为乘数 https stackoverflow com questions 299304 why does javas hashcode i
  • 使用一对多 JOIN 进行更新(多列)

    我遇到了一个问题 我不确定这是否是预期的行为 我在网上搜索了答案 但我所能找到的只是关于最后更新的行以及查询后的值是多少 我知道在这种情况下不存在订单之类的东西 并且您无法提前确定其价值是多少 但就我而言 我正在更新不同的列 因此覆盖以前的