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
elseIndividual
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