将用户标记为非活跃用户,如果他们没有必需的记录。

huangapple go评论108阅读模式
英文:

Marking users as not active if they don't have required records

问题

我有一个简单的表格模型。每个用户都必须完成一些必要的“操作”。

用户
-ID
-姓名
-是否激活

操作
-ID
-名称

用户操作
-用户ID
-操作ID

我想找出所有没有在用户操作表中具有所有操作记录的用户。如果他们在用户操作中没有所有操作记录,我想将是否激活标记为false。

可能会有2万个用户,所以这个处理应该是高效的。

寻找在不使用游标的情况下完成此操作的最佳方法。

英文:

I have a simple table model. There are some required "Actions" that every user has to have completed.

  1. User
  2. -Id
  3. -Name
  4. -IsActive
  5. Actions
  6. -Id
  7. -Name
  8. UserActions
  9. -UserID
  10. -ActionID

I want to find all Users who don't have all the Action records in the UserAcitons table. If they don't have all actions records in UserActions, I want to mark IsActive as false.

There could be 20K users so this should be effecient to process.

Looking for the best way to do this without having a cursor.

答案1

得分: 2

假设 UserActions 表中的行是唯一的,您可以计算这两个表中的操作并进行比较:

  1. update u
  2. set isactive = (case when num_actions > total_actions then 1 else 0 end)
  3. from users u left join
  4. (select ua.userid, count(*) as num_actions
  5. from useractions ua
  6. group by ua.userid
  7. ) ua
  8. on ua.userid = u.id cross join
  9. (select count(*) as total_actions
  10. from actions a
  11. ) a;

SQL Server 不支持布尔值,因此这里使用 0 表示假,1 表示真。

英文:

Assuming rows in UserActions are unique, you can count the actions in the two tables and compare them:

  1. update u
  2. set isactive = (case when num_actions > total_actions then 1 else 0 end)
  3. from users u left join
  4. (select ua.userid, count(*) as num_actions
  5. from useractions ua
  6. group by ua.userid
  7. ) ua
  8. on ua.userid = u.id cross join
  9. (select count(*) as total_actions
  10. from actions a
  11. ) a;

SQL Server doesn't support booleans, so this uses 0 for false and 1 for true.

答案2

得分: 1

你忘记告诉我们一些细节,例如是否存在重复的操作,是否ids是唯一的等等。
对于非常简单的情况,我成功创建了以下示例:

  1. create table [User]
  2. (
  3. Id int not null primary key,
  4. Name varchar(50) not null,
  5. IsActive bit not null
  6. )
  7. create table [Actions]
  8. (
  9. Id int not null primary key,
  10. Name varchar(50) not null
  11. )
  12. GO
  13. create table [UserActions]
  14. (
  15. UserId int not null,
  16. ActionId int not null,
  17. foreign key (UserId) REFERENCES [User](Id),
  18. foreign key (ActionId) REFERENCES [Actions](Id)
  19. )
  20. GO
  21. insert into [User] values
  22. (1, 'Alice', 1),(2, 'Bob', 1),(3, 'Caroline', 1)
  23. insert into [Actions] values
  24. (1, 'eat'),(2,'drink'),(3,'sleep')
  25. insert into [UserActions] values
  26. (1,1),(1,2),(1,3),
  27. (2,1),(2,2),
  28. (3,1),(3,2),(3,1)
  29. GO
  30. update us
  31. set us.IsActive = 0
  32. from [User] us
  33. join
  34. (
  35. select ua.UserId, COUNT(distinct ua.ActionId) as ActionCount
  36. from [UserActions] ua
  37. group by ua.UserId
  38. ) as uac on uac.UserId = us.Id
  39. where uac.ActionCount < (select count(*) from [Actions])
  40. select * from [User] us

提供以下结果:

  1. Id Name IsActive
  2. ----------- ---------- --------
  3. 1 Alice 1
  4. 2 Bob 0
  5. 3 Caroline 0
英文:

You forgot to tell us some details, for example if there are duplicated actions, if ids are UNIQUE, etc.
for very simple scenario I managed to create the below example:

  1. create table [User]
  2. (
  3. Id int not null primary key,
  4. Name varchar(50) not null,
  5. IsActive bit not null
  6. )
  7. create table [Actions]
  8. (
  9. Id int not null primary key,
  10. Name varchar(50) not null
  11. )
  12. GO
  13. create table [UserActions]
  14. (
  15. UserId int not null,
  16. ActionId int not null,
  17. foreign key (UserId) REFERENCES [User](Id),
  18. foreign key (ActionId) REFERENCES [Actions](Id)
  19. )
  20. GO
  21. insert into [User] values
  22. (1, &#39;Alice&#39;, 1),(2, &#39;Bob&#39;, 1),(3, &#39;Caroline&#39;, 1)
  23. insert into [Actions] values
  24. (1, &#39;eat&#39;),(2,&#39;drink&#39;),(3,&#39;sleep&#39;)
  25. insert into [UserActions] values
  26. (1,1),(1,2),(1,3),
  27. (2,1),(2,2),
  28. (3,1),(3,2),(3,1)
  29. GO
  30. update us
  31. set us.IsActive = 0
  32. from [User] us
  33. join
  34. (
  35. select ua.UserId, COUNT(distinct ua.ActionId) as ActionCount
  36. from [UserActions] ua
  37. group by ua.UserId
  38. ) as uac on uac.UserId = us.Id
  39. where uac.ActionCount &lt; (select count(*) from [Actions])
  40. select * from [User] us

Provides de results below

> Id Name IsActive
> ----------- ---------- --------
> 1 Alice 1
> 2 Bob 0
> 3 Caroline 0

huangapple
  • 本文由 发表于 2020年1月4日 00:08:32
  • 转载请务必保留本文链接:https://go.coder-hub.com/59581739.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定