【问题标题】:How to properly specify condition: sum count = column value?如何正确指定条件:sum count = column value?
【发布时间】:2018-12-16 03:34:07
【问题描述】:

我正在更新系统,尝试创建原始表的“影子”表,通过触发器接收更改,但不使用原始表,因为我真的不喜欢原始程序的设计方式。

其中一个是团队配置表,其中包含所有用户及其团队 ID。具有相同团队 id 的用户属于同一团队。我正在尝试在此处创建触发器以将数据截获到新的团队历史日志中。 (1 行 / 1 个团队 ID) 但是由于在团队设置之后,表格的多行会被更新,并且更新不是批量完成的,因此很难判断新的团队设置何时结束。幸运的是有这个 member_count 列,可以用来统计成员数量,并确定与这个新的 team_id 相关的所有必要记录何时更新。

| team id     | uid | member_count |
|201701010800A| 1   | 3            |
|201701010800A| 2   | 3            |
|201701010800A| 3   | 3            |

我的问题是我应该如何在更新后触发器中指定这个条件。 这就是我现在要做的。但这似乎很hacky。我想还有更明智的表达方式。

if exists(
    select 1 from ( values (1) ) t(c) 
    outer apply (
        select count(team_id) tc, max(member_count) mx, min(member_count) mm
        from old_teamtable 
        where team_id = ( select top 1 team_id from inserted )
    ) e
    where tc = mx and mx = mm
)

【问题讨论】:

  • Count(team) = member_count with a group by on member_count,team_id 应该可以吗?做同样的事情,但对我来说似乎更简单
  • 是的,但我想去掉的部分是from ( value (1)) t(c) outer apply ,感觉有点无意义。
  • 我根本不懂触发器,但不幸的是我觉得这个问题很有趣......你能解释一下你需要这个过滤器的输出吗?当 count(Id) = member_count 时,我认为这是一个真实的(布尔值)。一个触发器是否同时处理两个或一个新行/更新?
  • 这取决于数据的提交方式,它可以为每个uid执行多个update set team_id=? where uid=?;,也可以为批量更新执行update set team_id=? where uid in (1,2,3)。我只使用inserted.team_id 来定位新的团队成员,并确定所有成员何时设置了新的team_id,这样我确信我不会错过任何成员。触发器可以多次调用,但只有在时机合适时才起作用。 team_id 是一个始终唯一的 id,这是它工作的另一个先决条件......

标签: sql-server tsql sql-server-2012 triggers


【解决方案1】:

这对你有用吗?

if exists (
    select  1 
    from    old_teamtable 
    where   team_id = (select top 1 team_id from inserted) 
    having  count(*) = max(member_count) 
    and     max(member_count) = min(member_count)
)

【讨论】:

    【解决方案2】:

    以下代码演示了一种基于对团队和用户表的插入来管理团队历史记录表的方法。触发器在每个insertTeamsAndUsers 之后触发。对于尚未在TeamHistory 中的新团队,将添加适当的行并标记为IsComplete = 0。然后通过检查受insert 影响的所有团队来更新TeamHistory,以查看他们是否拥有正确数量的用户。如果是这样,IsComplete 位将设置为 1,用于 TeamHistory 表中的相应行。

    -- Create sample tables.
    create table TeamsAndUsers ( Id Int Identity, TeamId Int, UserId Int, TeamMembers Int );
    
    create table TeamHistory ( Id Int Identity, TeamId Int, IsComplete Bit );
    go
    
    -- Create the trigger.
    create trigger UpdateTeamHistory
      on TeamsAndUsers
      after Insert
    as
      set nocount on
    
      -- Handle any teams we've not heard of before.
      insert into TeamHistory ( TeamId, IsComplete )
        select distinct TeamId, 0
          from inserted
          where TeamId not in ( select TeamId from TeamHistory );
    
      -- See if any teams have been completed, i.e. all of their members are present.
      update TeamHistory
        set IsComplete = 1
        where TeamId in (
          select TAU.TeamId from (
            -- TeamId   values touched by the INSERT ...
            select distinct TeamId from inserted ) as i inner join
              -- ... matched with corresponding incomplete teams in the team history ...
              TeamHistory as TH on TH.TeamId = i.TeamId and TH.IsComplete = 0 inner join
              -- ... matched with users currently assigned to the teams.
              TeamsAndUsers as TAU on TAU.TeamId = i.TeamId
        group by TAU.TeamId
        having Count( TAU.UserId ) = Max( TAU.TeamMembers ) );
    go
    
    -- Test the trigger.
    insert into TeamsAndUsers ( TeamId, UserId, TeamMembers ) values
      ( 101, 1, 3 ), ( 101, 2, 3 );
    select * from TeamsAndUsers;
    select * from TeamHistory;
    
    insert into TeamsAndUsers ( TeamId, UserId, TeamMembers ) values
      ( 101, 3, 3 );
    select * from TeamsAndUsers;
    select * from TeamHistory;
    
    insert into TeamsAndUsers ( TeamId, UserId, TeamMembers ) values
      ( 102, 4, 1 );
    select * from TeamsAndUsers;
    select * from TeamHistory;
    
    insert into TeamsAndUsers ( TeamId, UserId, TeamMembers ) values
      ( 103, 10, 2 );
    select * from TeamsAndUsers;
    select * from TeamHistory;
    
    insert into TeamsAndUsers ( TeamId, UserId, TeamMembers ) values
      ( 103, 11, 2 );
    select * from TeamsAndUsers;
    select * from TeamHistory;
    

    除此之外:update 中的 select 看起来相当笨拙,但这里已经很晚了。大概可以整理一下。

    【讨论】:

    • 谢谢,我觉得 IsComplete 部分很不错,虽然它们对数据报告没有用处,但应该记录不完整的部分以发现故障。
    猜你喜欢
    • 1970-01-01
    • 2011-03-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多