2013-07-10 39 views
-1

在最後一個查詢中,將結果中的第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 
+0

根據您的狀態代碼,作業2有待處理狀態和完成狀態,您如何考慮/確定作業狀態是使用這兩個代碼進行處理的? –

+0

如果您在taskStatus IN(2,3)上搜索,則taskStatus永遠不會爲空。按taskStatus對輸入進行排序。 「處理它是否處理了一些任務,而其他處理正在進行中」尚不清楚。 – Paparazzi

+0

最後一個查詢中的狀態是針對整個批次的。批處理有幾個子任務,如果某些任務已完成而其他任務處於待處理狀態,則會將其視爲「正在處理」。 –

回答

0

我更喜歡select subquery作爲迄今爲止所見過的最直接的東西。

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 
1

UPDATE

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演示。

+0

是的,但這裏有一個問題,我沒有包括在我原來的問題中。對於錯誤,取消等項目,任務的狀態可能大於4。還有,我不得不對它做一些修改:「HAVING SUM(taskStatus) COUNT(*)* 1」 –

+0

@MicahBurnett您應該在您的問題擺在首位。這是非常重要的細節。現在,您想如何處理失敗任務的批處理? – peterm

+0

@MicahBurnett使用可能的解決方案查看更新的答案。假設如果批次包含至少一個狀態爲1到3的任務,則認爲它不完整=處理 – peterm

0

我解釋了你的意思,你基本上有3種不同的「批處理狀態」,大致等同於待處理,處理和完成的任務狀態。

因此,對於任何給定的任務狀態,你需要知道兩件事情:

  1. 這是否任務狀態指示任務已經啓動?
  2. 此任務狀態是否表示任務已完成?

如果你有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

在查詢AB ove,我使用值1表示待處理的「批處理狀態」,2表示處理的「批處理狀態」,4表示處理的「批處理狀態」。您可以創建一個BatchStatus表來真正定義這些值,儘管它不是必須的。

如果您需要根據任務狀態的其他組合派生其他「批處理狀態」,則您需要TaskStatus表上的其他標誌字段以及CASE語句中更復雜的邏輯。