首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >用于创建团队的Sql查询

用于创建团队的Sql查询
EN

Stack Overflow用户
提问于 2013-02-28 01:19:27
回答 3查看 290关注 0票数 2

我需要一个查询来将团队分配给一系列用户。数据如下所示:

代码语言:javascript
运行
复制
UserId  Category    Team
1       A           null
2       A           null
3       B           null
4       B           null
5       A           null
6       B           null
8       A           null
9       B           null
11      B           null

团队应该通过按用户and排序来创建,第一个用户and成为团队编号,连续的A是该团队的一部分,随后的B也是团队的一部分。B之后的第一个A开始了一个新的团队。始终至少有一个A和一个B。因此,在更新之后,数据应该如下所示:

代码语言:javascript
运行
复制
UserId  Category    Team
1       A           1
2       A           1
3       B           1
4       B           1
5       A           5
6       B           5
8       A           8
9       B           8
11      B           8

编辑:需要补充的是,用户id并不总是递增1。我编辑了示例数据以显示我的意思。此外,团队ID不一定严格是第一个用户的id,只要他们最终正确分组即可。例如,用户1-4可以都在团队“1”中,用户5和6在团队“2”中,用户8,9和11在团队“3”中。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2013-03-02 03:46:48

实际上,我最终选择了以下内容。它在半小时内完成了所有3个million+行的测试。

代码语言:javascript
运行
复制
declare @userid int
declare @team int
declare @category char(1)
declare @lastcategory char(1)
set @userid = 1
set @lastcategory='B'
set @team=0

while @userid is not null 
begin

  select @category = category from users where userid = @userid
  if @category = 'A' and @lastcategory = 'B'
  begin
   set @team = @userid
  end
  update users set team = @team where userid = @userid
  set @lastcategory = @category
  select @userid = MIN(userid) from users where userid > @userid
End
票数 0
EN

Stack Overflow用户

发布于 2013-02-28 01:46:26

首先,您可以用递增的数字标记每一行。然后,您可以使用left join查找之前的用户。如果前一个用户的类别为'B',而当前用户的类别为'A',这意味着新团队的开始。然后,团队编号是在当前UserId之前启动新团队的最后一个UserId

使用SQL Server 2008语法:

代码语言:javascript
运行
复制
; with  numbered as
        (
        select  row_number() over (order by UserId) rn
        ,       *
        from    Table1
        )
,       changes as
        (
        select  cur.UserId
        ,       case
                when prev.Category = 'B' and cur.Category = 'A' then cur.UserId
                when prev.Category is null then cur.UserId
                end as Team
        from    numbered cur
        left join
                numbered prev
        on      cur.rn = prev.rn + 1
        )
update  t1
set     Team = team.Team
from    Table1 t1
outer apply
        (
        select  top 1 c.Team
        from    changes c
        where   c.UserId <= t1.UserId
                and c.Team is not null
        order by
                c.UserId desc
        ) as team;

Example at SQL Fiddle.

票数 4
EN

Stack Overflow用户

发布于 2013-02-28 01:46:55

您可以使用递归CTE来完成此操作:

代码语言:javascript
运行
复制
with userCTE as
(
  select UserId
    , Category
    , Team = UserId
  from users where UserId = 1
  union all
  select users.UserId
    , users.Category
    , Team = case when users.Category = 'A' and userCTE.Category = 'B' then users.UserId else userCTE.Team end
  from userCTE
    inner join users on users.UserId = userCTE.UserId + 1
)
update users
set Team = userCTE.Team
from users
  inner join userCTE on users.UserId = userCTE.UserId
option (maxrecursion 0)

SQL Fiddle demo

编辑:

您可以更新CTE以获取此go:

代码语言:javascript
运行
复制
with userOrder as
(
  select *
    , userRank = row_number() over (order by userId)
  from users
)
, userCTE as
(
  select UserId
    , Category
    , Team = UserId
    , userRank
  from userOrder where UserId = (select min(UserId) from users)
  union all
  select users.UserId
    , users.Category
    , Team = case when users.Category = 'A' and userCTE.Category = 'B' then users.UserId else userCTE.Team end
    , users.userRank
  from userCTE
    inner join userOrder users on users.userRank = userCTE.userRank + 1
)
update users
set Team = userCTE.Team
from users
  inner join userCTE on users.UserId = userCTE.UserId
option (maxrecursion 0)

SQL Fiddle demo

编辑:

对于较大的数据集,您需要添加maxrecursion查询提示;我已经编辑了前面的查询以显示这一点。来自联机丛书:

指定此查询允许的最大递归数。number是介于0和32767之间的非负整数。如果指定0,则不应用任何限制。

在本例中,我将其设置为0,即不限制递归。

Query Hints

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/15118221

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档