从多行派生分组含义

时间:2013-07-10 19:34:45

标签: sql-server tsql

在上一个查询中,有哪些好方法可以将结果中的批处理2包含为“处理”?每个批处理都有几个子任务。批次的整体状态是我正在寻找的。

任务状态含义:

  • 1 =未决
  • 2 =处理
  • 3 =重试
  • 4 =完全
  • 5 =失败

批次状态:

  • 批处理1正在处理
  • 批处理2处于处理过程中,但尚未提取待处理任务。在这种情况发生前几秒钟,所以我对“睡眠”型状态不感兴趣。
  • 批处理3正在使用重试任务进行处理
  • 批处理4未处理,因为没有拾取任何内容。
  • 批处理5未处理,因为它已完成
  • 批处理6未处理,因为任务失败。

代码:

IF OBJECT_ID('tempdb..#t') IS NOT NULL DROP TABLE #t
CREATE TABLE #t (batchId INT, taskStatus INT)
INSERT INTO #t(batchId, taskStatus) VALUES
       (1, 1),
       (1, 2),
       (1, 4),
       (2, 1),
       (2, 1),
       (2, 4),
       (2, 4),
       (3, 3),
       (3, 4),
       (4, 1),
       (4, 1),
       (5, 4),
       (5, 4),
       (6, 5),
       (6, 4)

SELECT 
    batchId, 
    1 processing
FROM #t
WHERE taskStatus IN (2,3)
GROUP BY batchId

3 个答案:

答案 0 :(得分:1)

<强>更新

SELECT batchId, 1 processing
  FROM Table1
 GROUP BY batchId
HAVING SUM(CASE WHEN taskStatus IN(2,3) THEN 1 ELSE 0 END) > 0 
    OR (SUM(CASE WHEN taskStatus IN(1,4) THEN 1 ELSE 0 END) = COUNT(*) 
   AND COUNT(DISTINCT taskStatus) = 2)

这是 SQLFiddle 演示。

问题原始版本的原始答案:

SELECT batchId, 1 processing
  FROM Table1
 GROUP BY batchId
HAVING COUNT(*) * 4 > SUM(taskStatus)

此查询返回所有未完成任务的批次。

这是 SQLFiddle 演示。

答案 1 :(得分:0)

我解释你的意思是说你基本上有3种不同的“批处理状态”,大致相当于你的待处理,处理和完成的任务状态。

因此,对于任何给定的任务状态,您需要知道两件事:

  1. 此任务状态是否表示任务已启动?
  2. 此任务状态是否表示任务已完成?
  3. 如果您有一个TaskStatus表来定义这些状态,那么您可以在该表中添加一些标志列,如下所示:

    CREATE TABLE TaskStatus (
        taskStatusId INT,
        taskStatusName VARCHAR(50),
        taskStarted TINYINT,
        taskCompleted TINYINT
    );
    INSERT INTO TaskStatus values (1, 'Pending', 0, 0);
    INSERT INTO TaskStatus values (2, 'Processing', 1, 0);
    INSERT INTO TaskStatus values (3, 'Retrying', 1, 0);
    INSERT INTO TaskStatus values (4, 'Complete', 1, 1);
    

    现在,您可以使用以下查询的CASE语句中定义的逻辑派生“批处理状态”:

    select
      Task.batchId,
      CASE
        WHEN max(TaskStatus.taskStarted) = 0 AND min(TaskStatus.taskCompleted) = 0 THEN 1
        WHEN max(TaskStatus.taskStarted) > 0 AND min(TaskStatus.taskCompleted) = 0 THEN 2
        WHEN max(TaskStatus.taskStarted) > 0 AND min(TaskStatus.taskCompleted) > 0 THEN 4
      END as batchStatusId
    FROM Task
    INNER JOIN TaskStatus on
      Task.taskStatus = TaskStatus.taskStatusId
    group by
      Task.batchId
    

    sqlfiddle sample

    在上面的查询中,我使用值1表示待处理的“批处理状态”,2表示处理的“批处理状态”,4表示完成的“批处理状态”。您可以创建一个BatchStatus表来真正定义这些值,但不一定非必要。

    如果您需要根据任务状态的其他组合派生其他“批处理状态”,那么您需要在TaskStatus表上添加其他标志字段,并在CASE语句中使用更复杂的逻辑。

答案 2 :(得分:0)

我更喜欢选择子查询,这是迄今为止我见过的最直接的。

SELECT 
    t.batchId, 
    CASE 
        WHEN EXISTS(SELECT 1 FROM #t WHERE taskStatus IN (2,3) AND batchId = t.batchId) THEN 1 
        WHEN EXISTS(SELECT 1 FROM #t WHERE taskStatus=1 AND batchId = t.batchId) AND EXISTS(SELECT 1 FROM #t WHERE taskStatus=4 AND batchId = t.batchId) THEN 1
        ELSE 0 
    END processing  
FROM #t t
GROUP BY batchId