表连接以获得结果
Tables joins to get result
这是需要更新的table。
TABLE A
-------------------
ID UserID Value
-------------------
1 1 1A
2 1 1B
3 1 1C
4 2 2A
5 3 3A
6 4 4A
我有一个临时文件 table,其中包含已更新用户的新值。
TEMP TABLE
-------------
UserID Value
-------------
1 1A --existing
1 1D --new
2 2B --new
我想知道如何更新 TABLE A 以反映 TEMP TABLE 中的新值。预期结果将是:
TABLE A
-------------------
ID UserID Value
-------------------
1 1 1A
7 1 1D
8 2 2B
5 3 3A
6 4 4A
我有两个想法:
- 先删除再插入。使用左连接确定哪些值不再存在,然后删除它们。然后使用右连接确定哪些值是新值,然后插入它们。
- 也许我可以使用 MERGE,但我很清楚如何实现它。
测试环境
IF OBJECT_ID('tempdb..#tableA') IS NOT NULL
BEGIN
DROP TABLE #tableA
END
IF OBJECT_ID('tempdb..#tempTable') IS NOT NULL
BEGIN
DROP TABLE #tempTable
END
CREATE TABLE #tableA
(
ID int identity(1,1),
UserID int,
Value nvarchar(50)
)
CREATE TABLE #tempTable
(
UserID int,
Value nvarchar(50)
)
INSERT INTO #tableA([UserID], [Value])
VALUES (1, '1A'),
(1, '1B'),
(1, '1C'),
(2, '2A'),
(3, '3A'),
(4, '4A')
INSERT INTO #tempTable([UserID], [Value])
VALUES (1, '1A'),
(1, '1D'),
(2, '2B')
SELECT * FROM #tableA
SELECT * FROM #tempTable
编辑:以下解决方案从 TABLE A 中删除 ID (1,2,3,4),但我只想删除 (2,3,4)。这是因为ID 1已经存在于TABLEA中,不需要删除再插入
Delete
From TableA A
Where Exists
(
Select *
From TempTable T
Where T.UserId = A.UserId
)
我已经找到了解决方案,但我发现它很乱。有没有办法让它变得更好?
-- This will get the IDS (1,2,3,4) from TABLE A
SELECT * INTO #temp1 FROM #tableA
WHERE EXISTS
(
Select *
From #tempTable T
Where T.UserId = #tableA.UserId
)
--This will get the ID (1) from TABLE A. I do not want this deleted.
SELECT * INTO #temp2 FROM #tableA
WHERE EXISTS
(
Select *
From #tempTable T
Where T.UserId = #tableA.UserId AND T.[Value]=#tableA.Value
)
--LEFT JOIN to only delete the IDS (2,3,4)
DELETE FROM #tableA
WHERE EXISTS
(
SELECT *
FROM #temp1 a LEFT JOIN #temp2 b
ON a.UserID=b.UserID AND a.Value=b.Value
WHERE b.UserID IS NULL AND b.Value IS NULL
)
由于您想删除未出现在您的临时文件中的记录 Table,我会使用 Delete/Insert 方法:
Delete
From TableA A
Where Exists
(
Select *
From TempTable T
Where T.UserId = A.UserId
)
Insert
Into TableA
(UserId, Value)
Select T.UserId, T.Value
From TempTable T
Where Not Exists
(
Select *
From TableA A
Where A.UserId = T.UserId
And A.Value = T.Value
)
您也可以使用这些Outer Join
方法:
Delete A
From TableA A
Join TempTable T On T.UserId = A.UserId
Insert
Into TableA
(UserId, Value)
Select T.UserId, T.Value
From TempTable T
Left Join TableA A On A.UserId = T.UserId
And A.Value = T.Value
Where A.UserId Is Null
就我个人而言,Right Joins
只是伤了我的脑子,所以请随意更改顺序。
--This will remove all records which have at least one row with a matching UserID in tempTable and which don't have a row that matches on both UserID and Value.
DELETE
TableA A
WHERE
A.UserID IN (SELECT DISTINCT USerID FROM TempTable)
AND NOT EXISTS
(
Select 1
From TempTable T
Where T.UserId = A.UserId
AND T.Value= A.Value
)
--This will add any rows from temptable that don't have a match already in TableA
INSERT INTO TableA(UserId, Value)
SELECT DISTINCT UserID,Value
FROM TempTable T
WHERE NOT EXISTS (SELECT 1 FROM TableA A
WHERE T.UserID=A.UserID
AND T.value=A.Value)
这会得到你想要的结果。如果它是一个巨大的结果集——现实生活中的 table 或数百万行,那么可能会影响性能,需要退后一步。否则,会成功的
这是需要更新的table。
TABLE A
-------------------
ID UserID Value
-------------------
1 1 1A
2 1 1B
3 1 1C
4 2 2A
5 3 3A
6 4 4A
我有一个临时文件 table,其中包含已更新用户的新值。
TEMP TABLE
-------------
UserID Value
-------------
1 1A --existing
1 1D --new
2 2B --new
我想知道如何更新 TABLE A 以反映 TEMP TABLE 中的新值。预期结果将是:
TABLE A
-------------------
ID UserID Value
-------------------
1 1 1A
7 1 1D
8 2 2B
5 3 3A
6 4 4A
我有两个想法:
- 先删除再插入。使用左连接确定哪些值不再存在,然后删除它们。然后使用右连接确定哪些值是新值,然后插入它们。
- 也许我可以使用 MERGE,但我很清楚如何实现它。
测试环境
IF OBJECT_ID('tempdb..#tableA') IS NOT NULL
BEGIN
DROP TABLE #tableA
END
IF OBJECT_ID('tempdb..#tempTable') IS NOT NULL
BEGIN
DROP TABLE #tempTable
END
CREATE TABLE #tableA
(
ID int identity(1,1),
UserID int,
Value nvarchar(50)
)
CREATE TABLE #tempTable
(
UserID int,
Value nvarchar(50)
)
INSERT INTO #tableA([UserID], [Value])
VALUES (1, '1A'),
(1, '1B'),
(1, '1C'),
(2, '2A'),
(3, '3A'),
(4, '4A')
INSERT INTO #tempTable([UserID], [Value])
VALUES (1, '1A'),
(1, '1D'),
(2, '2B')
SELECT * FROM #tableA
SELECT * FROM #tempTable
编辑:以下解决方案从 TABLE A 中删除 ID (1,2,3,4),但我只想删除 (2,3,4)。这是因为ID 1已经存在于TABLEA中,不需要删除再插入
Delete
From TableA A
Where Exists
(
Select *
From TempTable T
Where T.UserId = A.UserId
)
我已经找到了解决方案,但我发现它很乱。有没有办法让它变得更好?
-- This will get the IDS (1,2,3,4) from TABLE A
SELECT * INTO #temp1 FROM #tableA
WHERE EXISTS
(
Select *
From #tempTable T
Where T.UserId = #tableA.UserId
)
--This will get the ID (1) from TABLE A. I do not want this deleted.
SELECT * INTO #temp2 FROM #tableA
WHERE EXISTS
(
Select *
From #tempTable T
Where T.UserId = #tableA.UserId AND T.[Value]=#tableA.Value
)
--LEFT JOIN to only delete the IDS (2,3,4)
DELETE FROM #tableA
WHERE EXISTS
(
SELECT *
FROM #temp1 a LEFT JOIN #temp2 b
ON a.UserID=b.UserID AND a.Value=b.Value
WHERE b.UserID IS NULL AND b.Value IS NULL
)
由于您想删除未出现在您的临时文件中的记录 Table,我会使用 Delete/Insert 方法:
Delete
From TableA A
Where Exists
(
Select *
From TempTable T
Where T.UserId = A.UserId
)
Insert
Into TableA
(UserId, Value)
Select T.UserId, T.Value
From TempTable T
Where Not Exists
(
Select *
From TableA A
Where A.UserId = T.UserId
And A.Value = T.Value
)
您也可以使用这些Outer Join
方法:
Delete A
From TableA A
Join TempTable T On T.UserId = A.UserId
Insert
Into TableA
(UserId, Value)
Select T.UserId, T.Value
From TempTable T
Left Join TableA A On A.UserId = T.UserId
And A.Value = T.Value
Where A.UserId Is Null
就我个人而言,Right Joins
只是伤了我的脑子,所以请随意更改顺序。
--This will remove all records which have at least one row with a matching UserID in tempTable and which don't have a row that matches on both UserID and Value.
DELETE
TableA A
WHERE
A.UserID IN (SELECT DISTINCT USerID FROM TempTable)
AND NOT EXISTS
(
Select 1
From TempTable T
Where T.UserId = A.UserId
AND T.Value= A.Value
)
--This will add any rows from temptable that don't have a match already in TableA
INSERT INTO TableA(UserId, Value)
SELECT DISTINCT UserID,Value
FROM TempTable T
WHERE NOT EXISTS (SELECT 1 FROM TableA A
WHERE T.UserID=A.UserID
AND T.value=A.Value)
这会得到你想要的结果。如果它是一个巨大的结果集——现实生活中的 table 或数百万行,那么可能会影响性能,需要退后一步。否则,会成功的