Sql server 如何在SQL语句中使用条件语句

Sql server 如何在SQL语句中使用条件语句,sql-server,Sql Server,我试图完成的是Groupcolumn 如果一个任务有多个用户在处理它,那么我想将其标记为团队其他个人 Task Sub-Task User Group 1234 9999 A Team 1234 9998 B Team 1234 9997 C Team 2345 6666 A Team 2345 6665 B Team

我试图完成的是
Group
column

如果一个任务有多个用户在处理它,那么我想将其标记为
团队
其他
个人

Task    Sub-Task    User    Group
1234    9999             A  Team
1234    9998             B  Team
1234    9997             C  Team

2345    6666             A  Team
2345    6665             B  Team

3456    5555             A  Individual A
4567    4444             B  Individual B
5678    3333             C  Individual C

您可以使用window函数
OVER()
。当
COUNT()
大于1时
Team
else
Individual

select  *,
        case when count(User) over (partition by Task) > 1
             then 'Team' 
             else 'Individual' 
             end
from    yourtable

另一个选项是设置一个派生表(作为CTE或内联),该表统计每个任务的用户数。然后,您可以使用它来显示所需的组(与@Squirrel的答案非常类似,只是用派生记录集替换窗口函数)


这是你想要的吗

SELECT Task, SubTask, [User], [Group] = CASE WHEN GroupCount > 1 THEN 'Group' ELSE 'Individual' END
FROM (
    SELECT *, [GroupCount] = (SELECT COUNT(*) FROM TestTable AS B WHERE B.Task = A.Task)
    FROM TestTable AS A) AS C
我的2美分:

CREATE TABLE #tmp
(
  [Id] BIGINT IDENTITY(1, 1) PRIMARY KEY CLUSTERED,
  [Task] INT,
  [SubTask] INT,
  [User] NCHAR(1),
  [Group] NVARCHAR(32)
)

INSERT INTO #tmp ([Task], [SubTask], [User], [Group]) VALUES (1234, 9999, 'A', 'Team');
INSERT INTO #tmp ([Task], [SubTask], [User], [Group]) VALUES (1234, 9998, 'B', 'Team');
INSERT INTO #tmp ([Task], [SubTask], [User], [Group]) VALUES (1234, 9997, 'C', 'Team');
INSERT INTO #tmp ([Task], [SubTask], [User], [Group]) VALUES (2345, 6666, 'A', 'Team');
INSERT INTO #tmp ([Task], [SubTask], [User], [Group]) VALUES (2345, 6665, 'B', 'Team');
INSERT INTO #tmp ([Task], [SubTask], [User], [Group]) VALUES (3456, 5555, 'A', 'Individual A');
INSERT INTO #tmp ([Task], [SubTask], [User], [Group]) VALUES (4567, 4444, 'B', 'Individual B');
INSERT INTO #tmp ([Task], [SubTask], [User], [Group]) VALUES (5678, 3333, 'C', 'Individual C');

SELECT          [A].[Task],
                [B].[SubTask],
                [B].[User],
                CASE [A].[Cnt]
                WHEN 1 THEN 'Individual ' + [User]
                ELSE 'Team'
                END AS [GroupCalculated],
                [Group],
                [A].[Cnt]

FROM (          SELECT          [Task],
                                COUNT(*) AS [Cnt]
                FROM            #tmp
                GROUP BY        [Task]) AS [A]

INNER JOIN      #Tmp AS [B]
    ON          [B].[Task] = [A].[Task];

DROP TABLE #tmp;

窗口函数是处理这个问题的一个很好的方法。使用
COUNT
窗口函数的棘手之处在于它不允许您执行
COUNT(DISTINCT…)
。因此,如果用户有2个子任务,当我猜您希望它返回1时,它将返回2

但是,我们可以使用
MIN
MAX
窗口函数来查看一个任务是否只有一个用户

MIN([user])OVER(按任务划分)
将获得结果集中每个任务的“最小”用户值。同样,
MAX
将获得“最大值”。如果它们相同,则意味着该任务只有一个用户,即使同一用户有多个子任务

SELECT
    task,
    subtask,
    [user],
    CASE
        WHEN MIN([user]) OVER (PARTITION BY task) = MAX([user]) OVER (PARTITION BY task)
        THEN 'Individual ' + [user]
        ELSE 'Team'
    END
FROM Tasks
如果没有窗口功能,这也是一种合适的方法,这与其他答案类似,但我认为我应该在这里包括它,注意它只统计不同的用户

SELECT
    A.task,
    A.subtask,
    A.[user],
    CASE
        WHEN B.user_count = 1
        THEN 'Individual ' + [user]
        ELSE 'Team'
    END
FROM Tasks A 
INNER JOIN 
    (
        SELECT 
            task,
            COUNT(DISTINCT [user]) user_count
        FROM #tmp
        GROUP BY
            task
    ) B 
ON      A.task = B.task

由于您计划在一个相当大的表上运行此功能,因此测试这两种解决方案的性能可能会有所帮助。

谢谢Zack。我将尝试这两种方法,因为我将处理2000万个结果,而且我忘记添加“我也将执行不同的任务计数”在我查看此示例时,OP的示例将用户附加到“个人”。我想您可以将
MAX(User)
添加到
TasksGroupedByUser
CTE中,然后将其连接到“个人”。另外,我认为将
COUNT(*)
更改为
COUNT(独立用户)
会更好。我正在考虑一个场景,同一个用户有多个子任务,但仍然是该任务的唯一用户。@EilertHjelmeseth:谢谢你的评论。我更新了答案以反映您的建议。虽然我认为在OP部分,将子任务作为第二列是糟糕的设计:我会有一个
Task
属性,然后是
ParentTask
属性。我注意到你说你在处理数百万条记录,可能值得考虑的是,如果性能成为很大的负担,在插入/更新/删除时更新并保持该字段的触发器。OP没有提到这样的场景,但如果一个任务有多个子任务,但所有子任务都与单个用户关联,我猜OP仍然希望看到“个人X”而不是“团队”因为事实上它只是一个人。我相信这个查询会标记为“Team”,不幸的是,
count(…)over(…)
不允许
count(DISTINCT…)over(…)
来解决这个问题。我们不知道OP是否没有提到,我认为将
COUNT(*)
更改为
COUNT(DISTINCT User)
会有帮助,以防同一用户有多个子任务,但该用户仍然是该任务的唯一用户。谢谢Eilert。我正在全力以赴。让我学会用不同的方法解决问题。
SELECT
    A.task,
    A.subtask,
    A.[user],
    CASE
        WHEN B.user_count = 1
        THEN 'Individual ' + [user]
        ELSE 'Team'
    END
FROM Tasks A 
INNER JOIN 
    (
        SELECT 
            task,
            COUNT(DISTINCT [user]) user_count
        FROM #tmp
        GROUP BY
            task
    ) B 
ON      A.task = B.task