0

这是场景:

表: CallMain:

Call_ID = PK (INT) 已放弃 (INT) 1 或 NULL

呼叫保持:

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 从上面可以看出,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,分组时,您会得到多个结果CallEnd。这意味着对于每个Call_ID, Abandoned组合,这些列的唯一值超过 1 个。

您必须决定要显示哪些值。例如,您可以选择像这样取最大值:

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 所做的函数。我不知道你的期望结果是什么。

于 2013-03-20T22:07:47.167 回答
0

这是因为你分组

CallHold.EndTime , CallHold.StartTime

这会返回多个条目,因为您在 CallMain 中的每个条目都得到一行。这些需要从 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 回答