使用另一个表的结果更新一个表

时间:2015-02-04 00:01:55

标签: sql sql-server tsql

我有一个包含3列的TABLE(Classes_Teachers)(classID - INT,teacherID INT,isActive BOOLEAN)。

我读了一个新文件的内容并创建了一个表(StudentsTemp),它具有相同的列,但是具有最新的数据,并希望“合并”这两个。

我可以使用EXCEPT AND JOIN轻松完成此操作,但这会删除StudentTemp中不存在的学生中的任何行,但是我需要能够将isActive设置为false,因为我必须保留报告的数据目的。

这是一个多关系的“JOIN”表,因此它没有一个主键。

所以例如

生:

+---------------------------------+
| ClassID   TeacherID   isActive  |
+---------------------------------+
| 1         2           1         |
| 1         12          1         |
| 1         13          0         |
| 5         10          1         |
+---------------------------------+

学生TEMP

+---------------------------------+
| ClassID   TeacherID   isActive  |
+---------------------------------+
| 1         2           1         |
| 1         13          1         |
| 1         6           1         |
+---------------------------------+

在这种情况下,教师10不再教授5级,因此该条目通常会被“删除”,但我只想将“isActive”更改为0

教师12也不再教授1级,所以这应该将isActive改为0。

现在,教师13教授第1课; ie现在是“活跃的”所以这个变化isActive为1

最后,有一个全新的教师(id = 6)教授classID为1,因此按行插入行。

我需要学生这样结束:

    +---------------------------------+
    | ClassID   TeacherID   isActive  |
    +---------------------------------+
    | 1         2           1         |
    | 1         12          0         |
    | 1         13          1         |
    | 5         10          0         |
    | 1         6           1         |
    +---------------------------------+

我可以通过创建3个临时表并使用EXCEPT AND JOIN来填充那些带有“删除”,“更改”和“插入”的表,然后对它们运行UPDATE AND INSERT,但我想知道是否存在更简单的方法,无需创建3个额外的临时表。

3 个答案:

答案 0 :(得分:1)

您是否尝试过使用合并声明?

https://msdn.microsoft.com/en-us/library/bb510625.aspx

答案 1 :(得分:1)

首先,插入新的teacherIDclassID组合。然后从Students表更新行。

CREATE TABLE #Students(
    ClassID     INT,
    TeachedID   INT,
    isActive    BIT
)
CREATE TABLE #StudentsTemp(
    ClassID     INT,
    TeachedID   INT,
    isActive    BIT
)
INSERT INTO #Students VALUES
(1, 2, 1), (1, 12, 1), (1, 13, 0), (5, 10, 1);
INSERT INTO #StudentsTemp VALUES
(1, 2, 1), (1, 13, 1), (1, 6, 1);


UPDATE s
    SET s.isActive = ISNULL(t.isActive, 0)
FROM #Students s
LEFT JOIN #StudentsTemp t
    ON t.ClassID = s.ClassID
    AND t.TeachedID = s.TeachedID

INSERT INTO #Students
SELECT
    ClassID,
    TeachedID,
    isActive
FROM #StudentsTemp t
WHERE
    NOT EXISTS(
        SELECT 1
        FROM #Students
        WHERE
            ClassID = t.ClassID
            AND TeachedID = t.TeachedID
    )


SELECT * FROM #Students

DROP TABLE #Students
DROP TABLE #StudentsTemp

<强> RESULT

ClassID     TeachedID   isActive
----------- ----------- --------
1           2           1
1           12          0
1           13          1
5           10          0
1           6           1

答案 2 :(得分:1)

尝试这样的事情:

MERGE Students AS T
USING Students_Temp AS S
ON (T.ClassId = S.ClassID AND T.TeacherID = S.TeacherID) 
WHEN NOT MATCHED BY TARGET
    THEN INSERT(ClassID, TeacherID, IsActive) VALUES(S.ClassID, S.TeacherID, S.IsActive)
WHEN NOT MATCHED BY SOURCE
    THEN UPDATE SET T.IsActive = 0
WHEN MATCHED 
    THEN UPDATE SET T.IsActive = S.IsActive