将数据从现有行复制到 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 中的另一现有行?的主要内容,如果未能解决你的问题,请参考以下文章

如何将数据从一个表复制到 MySQL 中的另一个新表?

将数据库列复制到Django中的另一个

需要帮助将 c-strings 从嵌入式 SQL fetch 复制到单独结构中的另一个 c-string

SQL - 将数据从同一表中的一列复制到另一列

如何批量覆盖现有文件?

将 SQL 数据库从一台服务器复制到 IBM netezza Aginity 工作台上的另一台服务器