0

シナリオは次のとおりです。

テーブル: CallMain:

Call_ID = PK (INT) Abandoned (INT) 1 または NULL のいずれか

保留中:

Hold_ID = PK (INT)

Call_ID = FK (INT)

開始時刻 (INT)

終了時間 (INT)

CallMain テーブルに保持されている各コールには、1、0、または多数の保留レコードがあります。通話が保留になるたびに、保留の StartTime と保留の EndTime を持つ 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 として返す必要があります。保留レコードが 1 つのコールは正しく表示されます。LEFT OUTER JOIN によって返される NULLS は、ISNULL() 関数で管理され、その呼び出しに実質的に保持時間がないため、ゼロに置き換えられます。

私の問題は、通話に複数の保留レコードがある場合、結果に 2 回表示されることです。つまり、Call_ID、HoldPeriod です。

212、254

213、154

214、158

214、25

214, 10 上記のように、Call 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 順

4

2 に答える 2

0

あなた自身がすでに言ったように。CallStart、 、 でグループ化すると、CallAns複数の結果が返されますCallEndCall_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

または、おそらくもっと論理的に、SUMHoldPeriod で行ったように関数を使用します。結果としてあなたが何を期待しているのかはわかりません。

于 2013-03-20T22:07:47.167 に答える
0

でグループ化しているからです。

CallHold.EndTime , CallHold.StartTime

CallMain のエントリごとに 1 つの行を取得していたため、複数のエントリが返されています。これらは group by から削除する必要があり、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
于 2013-03-20T22:13:17.280 に答える