SQL多行成单行,但并非总是如此

时间:2014-08-06 00:40:16

标签: sql-server pivot union

我有一个实时数据库,可以在登录时显示呼叫中心代理。代理可以作为语音代理或聊天代理或两者登录,每个登录都显示在单独的行中;

如果她登录到两者;

 AgentID | State    |ReasonCode  |LoginDur  |StateDur       |Domain
 --------------------------------------------------------------------
   1301    | NotReady   |Lunch       |01:23:12  |00:23:21       |1
   1301    | Ready      |Undefined   |00:57:12  |00:00:12       |5

域1用于语音登录,5用于聊天登录,AgentID是公分母。现在我想做的是将两者结合在一起;

 AgtID | V-State |V-ReCode |V-LogDur |V-StDur |C-State|C-RCode  |C-LogDur  |C-StDur |
-------------------------------------------------------------------------------------------
1301    |NotReady|Lunch    |01:23:12 |00:23:21|Ready  |Undefined|00:57:12  |00:00:12

如果座席同时以语音和聊天代理身份登录,我可以使用下面的查询来实现;

    SELECT AgentID, V-State, V-StDur, V-LogDur, V-RCode, C-State, C-StDur, C-LogDur, C-RCode 
FROM(SELECT
ART1.AgentID AS AgentID,
ART1.AgtState AS V-State,
ART2.AgtState AS C-State,
ART1.StateDur AS V-StDur,
ART2.StateDur AS C-StDur,
ART1.LoginDur AS V-LogDur,
ART2.LoginDur AS C-LogDur,
ART1.ReasonCode AS V-RCode,
ART2.ReasonCode AS C-RCode
FROM AgentRealTime ART1, AgentRealTime ART2
WHERE ART1.AgentID = ART2.AgentID AND
ART1.DomainID = 1 AND ART2.DomainID=5
)
AS AGRT

但是,仅当代理登录到两者时才有效。我还有另外两个案例要报道;如果代理仅作为语音代理或仅作为聊天代理登录。对于纯语音登录,我使用此查询;

    SELECT
AgentID=ART.AgentID,
V-State=ART.AgtState,
C-State=NULL,
V-StDur=ART.StateDur,
C-StDur=NULL,
V-LogDur=ART.LoginDur,
C-LogDur=NULL,
V-RCode=ART.ReasonCode,
C-RCode=NULL
FROM AgentRealTime ART
WHERE ART.DomainID = 1

对于仅限聊天的登录,我使用此

    SELECT
AgentID=ART.AgentID,
V-State=NULL,
C-State=ART.AgtState,
V-StDur=NULL,
C-StDur=ART.StateDur,
V-LogDur=NULL,
C-LogDur=ART.LoginDur,
V-RCode=NULL,
C-RCode=ART.ReasonCode
FROM AgentRealTime ART
WHERE ART.DomainID = 5

和我UNION所有三个查询。如果代理以仅限语音或仅聊天方式登录,则此整体查询会显示一行。但如果代理登录到两者,我最终会得到三行;

AgtID | V-State |V-ReCode |V-LogDur |V-StDur |C-State|C-RCode  |C-LogDur  |C-StDur |
-------------------------------------------------------------------------------------------
1301    |NotReady|Lunch    |01:23:12 |00:23:21|NULL   |NULL |NULL  |NULL

AgtID | V-State |V-ReCode |V-LogDur |V-StDur |C-State|C-RCode  |C-LogDur  |C-StDur |
-------------------------------------------------------------------------------------------
1301    |NotReady|Lunch    |01:23:12 |00:23:21|Ready  |Undefined|00:57:12  |00:00:12

AgtID | V-State |V-ReCode |V-LogDur |V-StDur |C-State|C-RCode  |C-LogDur  |C-StDur |
-------------------------------------------------------------------------------------------
1301    |NULL|NULL     |NULL |NULL  |Ready  |Undefined|00:57:12  |00:00:12

如果代理同时登录语音和聊天,如何将这三行合并为一行?或者您可以为此方案推荐的任何其他方法?

2 个答案:

答案 0 :(得分:0)

有几种方法可以做到这一点,我将主要用伪代码解释,因为你似乎知道你在做什么。

选项1:在后两个查询中,您可以添加AND NOT EXISTS / NOT IN

我稍微重写了你的where子句以使用INNER JOIN

  
    

查询2

         

选择....

         

ARTERE.DomainID = 5

         

AND ART.AgentID NOT IN

         

(SELECT ART1.AgentID

         

FROM AgentRealTime ART1

         

INNER JOIN AgentRealTime ART2 ON ART1.AgentID = ART2.AgentID

         

ART1.DomainID = 1

         

AND ART2.DomainID = 5)

  

在查询3中具有相同的条件

选项2:将值插入临时表以进行第一次查询。然后在每个附加查询中检查表中不存在AgentID。您可以通过多种方式完成此操作,我更喜欢左连接

查询1 - >进入诱惑

  
    

查询2 - >     选择......

         

FROM AgentRealTime ART

         

LEFT JOIN temptable t ON ART.agentID = t.agentID

         

ARTERE.DomainID = 1

         

AND t.agentID IS NULL

  

我个人更喜欢#temp表路由,因为你可以轻松地增强你的报告,一堆子查询和联合会在一段时间后变得混乱。您也可以使用代码来提高效率。

希望这有帮助,我第一次试图回答帖子。

答案 1 :(得分:0)

您只需要完全外部联接:

SELECT AgentID, V-State, V-StDur, V-LogDur, V-RCode, C-State, C-StDur, C-LogDur, C-RCode 
FROM(SELECT
COALEASE(ART1.AgentID,ART2.AgentID) AS AgentID,
ART1.AgtState AS V-State,
ART2.AgtState AS C-State,
ART1.StateDur AS V-StDur,
ART2.StateDur AS C-StDur,
ART1.LoginDur AS V-LogDur,
ART2.LoginDur AS C-LogDur,
ART1.ReasonCode AS V-RCode,
ART2.ReasonCode AS C-RCode
FROM AgentRealTime ART1 
FULL OUTER JOIN AgentRealTime ART2
ON ART1.AgentID = ART2.AgentID AND
WHERE ART1.DomainID = 1 AND ART2.DomainID=5 
)
AS AGRT

AgentId需要使用coalease。