以下是场景:
表: 的 CallMain:
Call_ID = PK(INT) 放弃(INT)1或NULL
CallHold:
Hold_ID = PK(INT)
Call_ID = FK(INT)
StartTime(INT)
EndTime(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订购
答案 0 :(得分: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
或者,或许更符合逻辑,使用{Hold}中的SUM
函数。我不知道你期待什么结果。
答案 1 :(得分: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