SQL:根据某些条件返回聚合结果

时间:2021-07-07 06:45:03

标签: sql sql-server tsql

我需要帮助才能根据某些列的值(例如状态聚合)在 SQL Server 中得出结论。 例如,下面是一个包含服务器任务及其状态的表格。

如果我想返回每个服务器的聚合状态,这里是规则:

  • 如果所有服务器任务都处于“提交”状态,则聚合服务器状态为“等待”
  • 如果所有任务都处于“完成”状态 - 聚合状态为“完成”
  • 如果不满足上述情况,则聚合服务器状态为“IN PROGRESS”

示例表:任务

<头>
服务器 Task_Status 任务
服务器1 正在运行 1-1
服务器1 完成 1-2
服务器1 已提交 1-3
服务器2 完成 2-1
服务器2 完成 2-2
服务器3 已提交 3-1
服务器3 已提交 3-2

示例查询结果:

<头>
服务器 完成
服务器1 进行中
服务器2 完成
服务器3 等待

到目前为止,我尝试使用以下查询但没有成功:

SELECT Server,
    CASE 
       WHEN Task_Status NOT IN ('RUNNING', 'COMPLETED') THEN 'AWAITING' -- Status SUBMITED
       WHEN Task_Status NOT IN ('RUNNING', 'SUBMITED') THEN 'DONE' -- Status COMPLETED
       ELSE 'IN PROGRESS'
    END Completion
FROM Tasks

6 个答案:

答案 0 :(得分:5)

你可以使用这个:

WITH table_name AS
(
    SELECT 'Server 1' AS server, 'RUNNING' AS task_status, '1-1' AS task UNION ALL
    SELECT 'Server 1' AS server, 'COMPLETED' AS task_status, '1-2' AS task UNION ALL
    SELECT 'Server 1' AS server, 'SUBMITTED' AS task_status, '1-3' AS task UNION ALL
    SELECT 'Server 2' AS server, 'COMPLETED' AS task_status, '2-1' AS task UNION ALL
    SELECT 'Server 2' AS server, 'COMPLETED' AS task_status, '2-2' AS task UNION ALL
    SELECT 'Server 3' AS server, 'SUBMITTED' AS task_status, '3-1' AS task UNION ALL
    SELECT 'Server 3' AS server, 'SUBMITTED' AS task_status, '3-2' AS task 
)

SELECT server,
    CASE 
        WHEN COUNT(DISTINCT task_status) = 1 AND MAX(task_status) = 'SUBMITTED' THEN 'AWAITING'
        WHEN COUNT(DISTINCT task_status) = 1 AND MAX(task_status) = 'COMPLETED' THEN 'DONE'
        ELSE 'IN PROGRESS'
    END AS completion
FROM table_name
GROUP BY server
ORDER BY server;

sqlfiddle 中测试

enter image description here

答案 1 :(得分:2)

select server, 
       case when count(distinct task_status) > 1 then 'in progress' 
            else case min(task_status) 
                   when 'completed' then 'done' 
                   when 'submitted' then 'awaiting' 
                   else 'some other result, perhaps an error' 
                 end 
        end result
  from your_table
group by server

答案 2 :(得分:2)

select Server,
  case  max(Task_Status) when 'COMPLETED' then 'DONE' else 
    (case min(Task_Status) when 'SUBMITTED' then 'AWAITING' else 'IN PROGRESS' end )
  end as Completion
from Table_1
group by Server

结果

Server  (Completion)
Server1     IN PROGRESS
Server2     DONE
Server3     AWAITING

答案 3 :(得分:1)

SELECT 
  server,
  CASE
    WHEN status = 3 THEN 'IN PROGRESS'
    WHEN status = 2 THEN 'WAITING'
    WHEN status = 1 THEN 'DONE'
  END as completion
FROM (
  SELECT
    server,
    MAX( CASE 
       WHEN task_status = 'RUNNING' THEN 3 
       WHEN task_status = 'SUBMITTED' THEN 2 
       WHEN task_status = 'COMPLETED' THEN 1
       END
    ) status
  FROM Tasks
  GROUP BY server
) result

答案 4 :(得分:1)

select 
    u.server,
    case 
        when u.cnt=u.cntCompleted then 'DONE'
        when u.cnt=u.cntSubmitted then 'AWAITING'
        else 'IN PROGRESS'
    end Completion
from
(
    select 
        server, 
        count(*) cnt,
        (select count(tstatus) from task t2 where t2.server=t1.server and t2.tstatus='SUBMITTED') cntSubmitted,
        (select count(tstatus) from task t2 where t2.server=t1.server and t2.tstatus='COMPLETED') cntCompleted
    from task t1
    group by server
) u

答案 5 :(得分:1)

感谢 Pham X Bach 提供表创建脚本。

您可以采用分步方法,计算不同的状态计数,然后应用以下逻辑:

WITH table_name AS
(
    SELECT 'Server 1' AS server, 'RUNNING' AS task_status, '1-1' AS task UNION ALL
    SELECT 'Server 1' AS server, 'COMPLETED' AS task_status, '1-2' AS task UNION ALL
    SELECT 'Server 1' AS server, 'SUBMITTED' AS task_status, '1-3' AS task UNION ALL
    SELECT 'Server 2' AS server, 'COMPLETED' AS task_status, '2-1' AS task UNION ALL
    SELECT 'Server 2' AS server, 'COMPLETED' AS task_status, '2-2' AS task UNION ALL
    SELECT 'Server 3' AS server, 'SUBMITTED' AS task_status, '3-1' AS task UNION ALL
    SELECT 'Server 3' AS server, 'SUBMITTED' AS task_status, '3-2' AS task 
)

select server, case when Completed_Count = total_Count then 'Done'
                    when Submitted_Count = total_Count then 'Awaiting'
                    else 'In Progress' end as Completion
from
(
SELECT server, count(case when task_status = 'Completed' then 1 end) as Completed_Count,
count(case when task_status = 'Submitted' then 1 end) as Submitted_Count,
count(*) as total_count
FROM table_name
GROUP BY SERVER
) as t
<头>
服务器 完成
服务器 1 进行中
服务器 2 完成
服务器 3 等待