在表中插入行以仅在其他行不存在时才模仿其他行

时间:2017-04-15 00:04:15

标签: sql sql-server-2008-r2

我有一个像这样设计的表格(名为 UserAccess ... ...

[ID], [UserID], [Active]

我有一个像这样设计的表格(名为 UserAccounts ... ...

[UserID], [Password], [Group]

UserAccess 表格中,我目前有以下数据......

1203, 'user1', 1
1203, 'user2', 1
1203, 'user4', 1
1202, 'user1', 1
1203, 'user8', 1
1202, 'user6', 1
1206, 'user2', 1
1205, 'user2', 1
1204, 'user1', 1
1204, 'user6', 1

UserAccounts 表格中,我目前有以下数据......

'user1', 'password', 'group1'
'user2', 'password', 'group10'
'user3', 'password', 'group1'
'user4', 'password', 'group4'
'user5', 'password', 'group10'
'user6', 'password', 'group10'
'user7', 'password', 'group2'
'user8', 'password', 'group10'

我想为属于'group10'的用户添加新行,以便他们模仿 UserAccess 表中尚未存在的'user2'的每一行。作为一个例子,结果应该是......

  1203, 'user1', 1
  1203, 'user2', 1
  1203, 'user4', 1
  1202, 'user1', 1
  1203, 'user8', 1
  1202, 'user6', 1
  1206, 'user2', 1
  1205, 'user2', 1
  1204, 'user1', 1
  1205, 'user6', 1
* 1203, 'user5', 1
* 1206, 'user5', 1
* 1205, 'user5', 1
* 1203, 'user6', 1
* 1206, 'user6', 1
* 1206, 'user8', 1
* 1205, 'user8', 1

新结果显示添加的行是前面带有星号的行。实现这一目标的最佳方法是什么?我试图使用这样的东西,但似乎无法得到我追求的结果,老实说,我似乎无法接近我想要的......

注意:@UserId应该通过每个用户进行更改。

DECLARE @ModelId varchar(30); SET @ModelId = 'user2';
INSERT INTO UserAccess ([ID], [UserID])
SELECT [ID], @UserId, FROM UserAccess
WHERE [UserID] = @ModelId

谢谢!

1 个答案:

答案 0 :(得分:1)

请尝试以下方法......

INSERT INTO UserAccess
SELECT ID,
       UserID,
       1
FROM UserAccounts outerUserAccounts,
     ( SELECT ID
       FROM UserAccess
       WHERE UserID = 'user2' ) AS selectedIDs
WHERE [Group] = 'Group10'
  AND NOT EXISTS ( SELECT *
                   FROM UserAccess
                   WHERE UserAccess.ID = selectedIDs.ID
                     AND UserAccess.UserID = outerUserAccounts.UserID );

我首先使用以下SQL语句确定ID的哪些值与指定的UserID(在本例中为user2)相关联...

SELECT ID
FROM UserAccess
WHERE UserID = 'user2'

然后,我在生成的表(我称之为CROSS JOIN)和selectedIDs上的用户属于指定UserAccounts的那些记录中填写Group(在此情况1}})。 (请注意Group10UserAccounts, selectedIDs相同。)

结果表包含需要插入UserAccounts CROSS JOIN selectedIDs的{​​{1}}和ID的值,但它也可能包含UserID中已存在的记录。因此,UserAccounts语句中添加了以下UserAccounts子句......

WHERE

此子句测试以查看主语句正在考虑的值是否在SELECT中不存在。

我的代码是针对使用以下脚本创建的示例数据库进行测试的......

NOT EXISTS ( SELECT *
             FROM UserAccess
             WHERE UserAccess.ID = selectedIDs.ID
             AND UserAccess.UserID = outerUserAccounts.UserID )

然后使用以下陈述检查结果......

UserAccess

输出符合要求。

如果您有任何问题或意见,请随时发表评论。