2013-03-20 103 views
0

這裏是場景:SQL SUM重複

表: CallMain:

CALL_ID = PK(INT) 廢棄(INT)1個或NULL

CallHold:

HOLD_ID = PK(INT)

CALL_ID = FK(INT)

開始時間(INT)

結束時間(INT)

在CallMain臺保持每個呼叫可以有1,0或許多保持記錄。每次呼叫進入保持狀態時,由FK以保持的開始時間和保持的結束時間創建記錄。

現在,在查詢返回此信息來顯示呼叫和其總保持時間,我相信,SQL是如下:

SELECT CallMain.Call_ID, CallMain.Abandoned, 
ISNULL((CallHold.EndTime - CallHold.StartTime),0) AS HoldPeriodSeconds 
FROM CTIStatCall 
LEFT OUTER JOIN CallHold ON CallMain.Call_ID = CallHold.Call_ID 

此查詢應返回的記錄爲沒有保持記錄通話與他們相關聯,並應將其作爲NULLS返回。帶有單個保持記錄的呼叫顯示正確。正在由LEFT OUTER JOIN返回的NULLS正在使用ISNULL()函數進行管理,並且被替換爲零,因爲該調用沒有保持時間。

我的問題在於,在呼叫具有多個保持其記錄將在結果即出現兩次: CALL_ID,HoldPeriod

212,254

213,154

214,158

214,25

214,10 如上所述,呼叫214具有多個持有記錄共計193.我想通了,查詢必須是:

SELECT 
    CallMain.Call_ID, 
    CallMain.Abandoned, 
    Sum(ISNULL((CallHold.EndTime - CallHold.StartTime), 0)) AS HoldPeriodSeconds 
FROM 
    CallMain 
LEFT OUTER JOIN 
    CallHold 
ON 
    CallMain.Call_ID = CallHold.Call_ID 
GROUP BY 
    CallMain.Call_ID, 
    CallMain.Abandoned 

我現在的問題是我在MainCall表,也將返回進一步列,CallStart,CallAns,CallEnd這些都是用於計算一些其他派生值。我返回這些並將它們添加到group by子句中,但它又回到顯示重複值。我怎樣才能解決這個問題?

我已經嘗試過:

SELECT CallMain.Call_ID, dateadd(s,CallMain.StartTime, '1970-01-01') AS StartTime, 
dateadd(s,CallMain.AnsTime, '1970-01-01') AS AnsTime, 
dateadd(s,CallMain.EndTime, '1970-01-01') AS EndTime, 
CallMain.Abandoned, 
(CallMain.AnsTime - CallMain.StartTime) AS RingPeriod, 
SUM(ISNULL((CallHold.EndTime - CallHold.StartTime),0)) AS HoldPeriod, 
(CallMain.EndTime - CallMain.AnsTime) - ISNULL((CallHold.EndTime - CallHold.StartTime),0) AS TalkPeriod 
FROM CallMain 
LEFT OUTER JOIN 
CallHold ON CallMain.Call_ID = CallHold.Call_ID 
    GROUP BY CallMain.Call_ID, CallMain.Abandoned, CallMain.StartTime, CallMain.EndTime, CallMain.AnsTime, CallHold.EndTime, CallHold.StartTime 

爲了通過CallMain.Call_ID

回答

0

正如你已經說了你自己。當您通過CallStart,CallAns,CallEnd進行分組時,您會得到多個結果。這意味着對於每個Call_ID, Abandoned組合,您有多個這些列的唯一值。

您必須決定要顯示哪些值。例如,你可以選擇做的最大值是這樣的:

SELECT 
    CallMain.Call_ID, 
    CallMain.Abandoned, 
    Sum(ISNULL((CallHold.EndTime - CallHold.StartTime), 0)) AS HoldPeriodSeconds, 
    (MAX(CallMain.AnsTime) - MAX(CallMain.StartTime)) AS RingPeriod, 
    .... 
FROM 
    CallMain 
LEFT OUTER JOIN 
    CallHold 
ON 
    CallMain.Call_ID = CallHold.Call_ID 
GROUP BY 
    CallMain.Call_ID, 
    CallMain.Abandoned 

或者,也許更符合邏輯,使用SUM功能像你這樣的HoldPeriod。我不知道你的期望是什麼。

0

這是因爲你被

CallHold.EndTime , CallHold.StartTime 

哪些是回饋多個條目,因爲你是在CallMain讓每個條目一行分組。這些需要從組中刪除,並從select語句中刪除或使用合適的聚合函數。它應該是這樣的......

SELECT CallMain.Call_ID, dateadd(s,CallMain.StartTime, '1970-01-01') AS StartTime, 
     dateadd(s,CallMain.AnsTime, '1970-01-01') AS AnsTime, 
     dateadd(s,CallMain.EndTime, '1970-01-01') AS EndTime, 
     CallMain.Abandoned, 
     (CallMain.AnsTime - CallMain.StartTime) AS RingPeriod, 
     SUM(ISNULL((CallHold.EndTime - CallHold.StartTime),0)) AS HoldPeriod, 
     (CallMain.EndTime - CallMain.AnsTime) - ISNULL((CallHold.EndTime - CallHold.StartTime),0) AS TalkPeriod 
    FROM CallMain 
LEFT OUTER JOIN 
     CallHold ON CallMain.Call_ID = CallHold.Call_ID 
GROUP BY CallMain.Call_ID, CallMain.Abandoned, CallMain.StartTime, CallMain.EndTime, CallMain.AnsTime