将数据从现有行复制到 SQL 中的另一现有行?
Posted
技术标签:
【中文标题】将数据从现有行复制到 SQL 中的另一现有行?【英文标题】:Copy data from one existing row to another existing row in SQL? 【发布时间】:2010-10-14 08:54:53 【问题描述】:我有一个表格,其中包含特定课程的跟踪数据,课程编号 6。
现在我为 11 号课程添加了新的跟踪数据。
每一行数据是针对一门课程的一个用户,因此对于分配到课程 6 和课程 11 的用户,有两行数据。
客户希望在 2008 年 8 月 1 日之后的任何时间完成第 6 课程的所有用户也将完成第 11 课程的标记。但是我不能只将 6 转换为 11,因为他们想保留课程的旧数据6.
因此,对于课程编号为 6、标记为完成且大于 2008 年 8 月 1 日的每一行,我想将完成数据写入包含该特定课程 11 跟踪的行用户。
我需要将课程 6 行中的数据转移到课程 11 行,以便将用户分数和发布完成日期等数据移至过去。
这是表的结构:
userID (int)
courseID (int)
course (bit)
bookmark (varchar(100))
course_date (datetime)
posttest (bit)
post_attempts (int)
post_score (float)
post_date (datetime)
complete (bit)
complete_date (datetime)
exempted (bit)
exempted_date (datetime)
exempted_reason (int)
emailSent (bit)
一些值将是 NULL 并且 userID/courseID 显然不会被保留,因为它已经在正确的位置。
【问题讨论】:
【参考方案1】:也许我读错了问题,但我相信您已经插入了课程 11 记录,只需使用课程 6 的数据更新符合您列出的条件的记录。
如果是这种情况,您需要使用UPDATE
...FROM
语句:
UPDATE MyTable
SET
complete = 1,
complete_date = newdata.complete_date,
post_score = newdata.post_score
FROM
(
SELECT
userID,
complete_date,
post_score
FROM MyTable
WHERE
courseID = 6
AND complete = 1
AND complete_date > '8/1/2008'
) newdata
WHERE
CourseID = 11
AND userID = newdata.userID
See this related SO question for more info
【讨论】:
有机会你可以向我解释一下 newdata 的工作原理,这看起来很方便,但我不太确定我明白了 @Ryan 你运行/验证了吗? newdata 是表别名。基本上,因为 select 语句正在查询我们正在更新的同一个表,如果我们说 update MyTable.complete_date = MyTable.complete_date,SQL 会感到困惑。我为 course=6 数据的查询起了一个新名称“newdata”,以避免这种混淆。 @跛脚鸭这实际上与我发布的版本等效吗?我总是看到更新的 From 子句,就好像我在做通常的选择一样。如果它是一个选择,那就是让课程按 6 过滤,然后按 11 过滤 - 这会得到一个空的结果集【参考方案2】:UPDATE c11
SET
c11.completed= c6.completed,
c11.complete_date = c6.complete_date,
-- rest of columns to be copied
FROM courses c11 inner join courses c6 on
c11.userID = c6.userID
and c11.courseID = 11 and c6.courseID = 6
-- and any other checks
我总是查看更新的 From 子句,就像普通的选择之一。实际上,如果您想在运行更新之前检查将更新的内容,您可以使用选择 c11.* 替换更新部分。看看我的跛脚鸭的答案。
【讨论】:
【参考方案3】:将一行中的值复制到同一表(或不同表)中的任何其他合格行:
UPDATE `your_table` t1, `your_table` t2
SET t1.your_field = t2.your_field
WHERE t1.other_field = some_condition
AND t1.another_field = another_condition
AND t2.source_id = 'explicit_value'
首先将表别名为 2 个唯一引用,以便 SQL 服务器可以区分它们
接下来,指定要复制的字段。
最后,指定控制行选择的条件
根据条件,您可以从单行复制到系列,也可以将系列复制到系列。您还可以指定不同的表,甚至可以使用子选择或连接来允许使用其他表来控制关系。
【讨论】:
它在 Microsoft SQL Server 中不起作用。错误消息:“t1”附近的语法不正确。 2 个表的更新在 Oracle 中也不起作用...可以使用上面的连接示例来解决这个限制。 在 postgres 我做了UPDATE your_table t1 SET your_field = t2.your_field FROM your_table t2 WHERE t1.other_field = 'some value' and t2.other_field ='some other value'
适用于 mysql 5.x 无变化
糟糕,这在 SQL Server 中不起作用,这样写似乎很直观【参考方案4】:
Use SELECT to Insert records
INSERT tracking (userID, courseID, course, bookmark, course_date, posttest, post_attempts, post_score, post_date, complete, complete_date, exempted, exempted_date, exempted_reason, emailSent)
SELECT userID, 11, course, bookmark, course_date, posttest, post_attempts, post_score, post_date, complete, complete_date, exempted, exempted_date, exempted_reason, emailSent
FROM tracking WHERE courseID = 6 AND course_date > '08-01-2008'
【讨论】:
hmm 好的,但是我可以做一个 WHERE 来检查 INSERT 和 SELECT 是否在同一个表中? 应该可以,举个我刚才加的例子试试。 如果需要的话,可能也应该将 complete_date 设置为当前日期。不过,这应该可以帮助您入门。【参考方案5】:试试这个:
UPDATE barang
SET ID FROM(SELECT tblkatalog.tblkatalog_id FROM tblkatalog
WHERE tblkatalog.tblkatalog_nomor = barang.NO_CAT) WHERE barang.NO_CAT <>'';
【讨论】:
【参考方案6】:这对于处理整个记录非常有效。
UPDATE your_table
SET new_field = sourse_field
【讨论】:
这会复制列,而不是行以上是关于将数据从现有行复制到 SQL 中的另一现有行?的主要内容,如果未能解决你的问题,请参考以下文章