使用 table_1 和 table_2 数据更新 table_2 数据/T-SQL
Updating table_2 data using table_1 and table_2 data / T-SQL
场景
user@website.com
需要在 table 2 中具有与 admin@website.com
.
相同的用户配置文件
目前 user@website.com
有 user_profile
50 而不是 user_profile
10 和 20。
描述
我想创建一个查询,在 Table_2 中输入与 user_email
user@website.com
相同的 id_profiles
,目前 admin@website.com
.
我们唯一知道的是 user_email
用户和 table/column 名称。
Table 1
id_user
user_email
1
admin@website.com
2
user@website.com
Table 2
id_user
user_profile
1
10
1
20
2
50
Table 2(预期数据):
id_user
user_profile
1
10
1
20
2
10
2
20
下面的查询没有按预期工作,因为它仅在 Table_2.
中没有包含 user_id '2' 的行时才插入数据
DECLARE @adminEmail nvarchar(255) = 'admin@website.com'
DECLARE @userEmail nvarchar(255) = 'user@website.com'
DECLARE @adminEmailID int = (SELECT id_user FROM Table_1
WHERE user_profile = @adminEmail);
INSERT INTO Table_2 (id_user, user_profile)
SELECT
(SELECT id_user FROM Table_1
WHERE user_email = @userEmail) AS id_user,
b.user_profile
FROM
Table_2 b
INNER JOIN
Table_1 a ON a.id_user = b.id_user
WHERE
NOT EXISTS (SELECT * FROM Table_2
WHERE id_user = (SELECT id_user FROM Table_1
WHERE user_email = @userEmail))
您可以为此使用 MERGE
。
注意以下几点:
- 您必须pre-filter源和目标tables,使用CTE、视图或派生的tables,否则您将最终删除整个 table。 不要陷入将所有条件都放在
ON
. 中的陷阱
- 您需要找到目标用户的 ID,以便根据该 ID 插入。您不能在
MERGE
中执行此操作,因为 JOIN
. 将没有匹配的行
DECLARE @adminEmail nvarchar(255) = 'admin@website.com';
DECLARE @userEmail nvarchar(255) = 'user@website.com';
DECLARE @userEmailID int = (SELECT id_user FROM Table_1
WHERE user_email = @userEmail);
WITH Source AS (
SELECT t2.*
FROM Table_2 t2
JOIN Table_1 t1 ON t1.id_user = t2.id_user
WHERE t1.user_email = @adminEmail
),
Target AS (
SELECT t2.*
FROM Table_2 t2
WHERE t2.id_user = @userEmailID
)
MERGE Target t
USING Source s ON s.user_profile = t.user_profile
WHEN NOT MATCHED BY TARGET THEN
INSERT (id_user, user_profile)
VALUES (@userEmailID, s.user_profile)
WHEN NOT MATCHED BY SOURCE THEN
DELETE
;
- 根据联接的复杂性,将此作为单独的
INSERT
和 DELETE
语句执行可能更容易且性能更高
DECLARE @adminEmail nvarchar(255) = 'admin@website.com';
DECLARE @userEmail nvarchar(255) = 'user@website.com';
INSERT Table_2 (id_user, user_profile)
SELECT t1User.id_user, t2.user_profile
FROM Table_2 t2
JOIN Table_1 t1Admin ON t1Admin.id_user = t2.id_user
AND t1Admin.user_email = @adminEmail
JOIN Table_1 t1User ON t1User.user_email = @userEmail
WHERE NOT EXISTS (SELECT 1
FROM Table_2 t2Existing
WHERE t2Existing.id_user = t1User.id_user
AND t2Existing.user_profile = t2.user_profile);
DELETE t2
FROM Table_2 t2
JOIN Table_1 t1User ON t1User.id_user = t2.id_user
AND t1User.user_email = @userEmail
WHERE NOT EXISTS (SELECT 1
FROM Table_2 t2Admin
JOIN Table_1 t1Admin ON t1Admin.id_user = t2Admin.id_user
WHERE t1Admin.user_email = @adminEmail
AND t2Admin.user_profile = t2.user_profile);
场景
user@website.com
需要在 table 2 中具有与 admin@website.com
.
目前 user@website.com
有 user_profile
50 而不是 user_profile
10 和 20。
描述
我想创建一个查询,在 Table_2 中输入与 user_email
user@website.com
相同的 id_profiles
,目前 admin@website.com
.
我们唯一知道的是 user_email
用户和 table/column 名称。
Table 1
id_user | user_email |
---|---|
1 | admin@website.com |
2 | user@website.com |
Table 2
id_user | user_profile |
---|---|
1 | 10 |
1 | 20 |
2 | 50 |
Table 2(预期数据):
id_user | user_profile |
---|---|
1 | 10 |
1 | 20 |
2 | 10 |
2 | 20 |
下面的查询没有按预期工作,因为它仅在 Table_2.
中没有包含 user_id '2' 的行时才插入数据DECLARE @adminEmail nvarchar(255) = 'admin@website.com'
DECLARE @userEmail nvarchar(255) = 'user@website.com'
DECLARE @adminEmailID int = (SELECT id_user FROM Table_1
WHERE user_profile = @adminEmail);
INSERT INTO Table_2 (id_user, user_profile)
SELECT
(SELECT id_user FROM Table_1
WHERE user_email = @userEmail) AS id_user,
b.user_profile
FROM
Table_2 b
INNER JOIN
Table_1 a ON a.id_user = b.id_user
WHERE
NOT EXISTS (SELECT * FROM Table_2
WHERE id_user = (SELECT id_user FROM Table_1
WHERE user_email = @userEmail))
您可以为此使用 MERGE
。
注意以下几点:
- 您必须pre-filter源和目标tables,使用CTE、视图或派生的tables,否则您将最终删除整个 table。 不要陷入将所有条件都放在
ON
. 中的陷阱
- 您需要找到目标用户的 ID,以便根据该 ID 插入。您不能在
MERGE
中执行此操作,因为JOIN
. 将没有匹配的行
DECLARE @adminEmail nvarchar(255) = 'admin@website.com';
DECLARE @userEmail nvarchar(255) = 'user@website.com';
DECLARE @userEmailID int = (SELECT id_user FROM Table_1
WHERE user_email = @userEmail);
WITH Source AS (
SELECT t2.*
FROM Table_2 t2
JOIN Table_1 t1 ON t1.id_user = t2.id_user
WHERE t1.user_email = @adminEmail
),
Target AS (
SELECT t2.*
FROM Table_2 t2
WHERE t2.id_user = @userEmailID
)
MERGE Target t
USING Source s ON s.user_profile = t.user_profile
WHEN NOT MATCHED BY TARGET THEN
INSERT (id_user, user_profile)
VALUES (@userEmailID, s.user_profile)
WHEN NOT MATCHED BY SOURCE THEN
DELETE
;
- 根据联接的复杂性,将此作为单独的
INSERT
和DELETE
语句执行可能更容易且性能更高
DECLARE @adminEmail nvarchar(255) = 'admin@website.com';
DECLARE @userEmail nvarchar(255) = 'user@website.com';
INSERT Table_2 (id_user, user_profile)
SELECT t1User.id_user, t2.user_profile
FROM Table_2 t2
JOIN Table_1 t1Admin ON t1Admin.id_user = t2.id_user
AND t1Admin.user_email = @adminEmail
JOIN Table_1 t1User ON t1User.user_email = @userEmail
WHERE NOT EXISTS (SELECT 1
FROM Table_2 t2Existing
WHERE t2Existing.id_user = t1User.id_user
AND t2Existing.user_profile = t2.user_profile);
DELETE t2
FROM Table_2 t2
JOIN Table_1 t1User ON t1User.id_user = t2.id_user
AND t1User.user_email = @userEmail
WHERE NOT EXISTS (SELECT 1
FROM Table_2 t2Admin
JOIN Table_1 t1Admin ON t1Admin.id_user = t2Admin.id_user
WHERE t1Admin.user_email = @adminEmail
AND t2Admin.user_profile = t2.user_profile);