基于多个列和行中的数据提取数据

时间:2013-05-08 02:21:57

标签: sql sql-server sql-server-2000

我有以下数据,这些数据代表进入我们中心并转移给顾问(CSO)的呼叫流程。

CallID   Sequence    Action          Location         Input    NextLocation

1135     0           CallStart       NULL             NULL     NULL    
1135     1           MenuStart       EFTPosHelpDesk   NULL     NULL    
1135     2           KeyPress        EFTPosHelpDesk   3        TransferCSO
1135     3           TransferEntry   EFTPosHelpDesk   NULL     NULL
1135     4           TransferFlag    NULL             NULL     NULL
1135     5           AccessNum       NULL             NULL     NULL
1135     6           Transfer        NULL             NULL     NULL
1135     7           Hangup          NULL             NULL     NULL

我正在使用MS SQL Management Studio 2005提取数据,但数据本身存储在MS SQL 2000服务器上。

数据库中记录了数百万次呼叫,我需要提取客户转移到CSO的CallID。告诉我呼叫转移到CSO的目标数据完全如下:

@Sequence 2 -> NextLocation = 'TansferCSO'
@Sequence 3 -> Action = 'TransferEntry'
@Sequence 4 -> Action = 'TransferFlag'
@Sequence 5 -> Action = 'AccessNum'
@Sequence 6 -> Action = 'Transfer'
@Sequence 7 -> Action = 'Hangup'

...它总是在那个序列中,但“序列”编号和“位置”会有所不同,因为有些调用平均可以运行50-70步,我们有100个IVR(位置)。

我对SQL很新,我尝试过使用FETCH和IF / ELSE,但没有成功。由于数据在MS SQL2000服务器上,ROW_NUMBER()不会工作。

非常感谢任何示例或建议。

1 个答案:

答案 0 :(得分:1)

这将根据所有6个条目(按任意顺序)为您提供已转移到CSO的所有呼叫(CallID)。

  select CallID
    from yourTable
   where Action in ('TransferEntry', 'TransferFlag',
                    'AccessNum', 'Transfer', 'Hangup')
      or NextLocation = 'TransferCSO'
group by CallID
  having count(distinct Action) = 6;

注意:假设NextLocation='TransferCSO'行包含不同的但具体的操作,例如“按键响应”


如果您确实需要确保6个事件是连续的,则可以使用以下内容。最后JOIN条件的微小变化也可以用于有序而不必连续。

create table #tmpCalls (CallID int, Sequence int, Action varchar(20));

select c.CallID, c.Sequence, c.Action
  from
(
      select CallID
        from yourTable
       where Action in ('TransferEntry', 'TransferFlag',
                        'AccessNum', 'Transfer', 'Hangup')
          or (Action = 'KeyPress' and NextLocation = 'TransferCSO')
    group by CallID
      having count(distinct Action) = 6
) a
  join yourTable c on c.CallID = a.CallID
 where c.Action in ('TransferEntry', 'TransferFlag',
                    'AccessNum', 'Transfer', 'Hangup')
    or (c.Action = 'KeyPress' and c.NextLocation = 'TransferCSO');

create clustered index #ix_tmpCalls on #tmpCalls(CallID, Sequence, Action);

select distinct a.CallID
  from #tmpCalls a                 -- or perhaps just:  b.Sequence > a.Sequence
  join #tmpCalls b on b.Action = 'TransferEntry' and b.Sequence = a.Sequence + 1
  join #tmpCalls c on c.Action = 'TransferFlag' and c.Sequence = b.Sequence + 1
  join #tmpCalls d on d.Action = 'AccessNum' and d.Sequence = c.Sequence + 1
  join #tmpCalls e on e.Action = 'Transfer' and e.Sequence = d.Sequence + 1
  join #tmpCalls f on f.Action = 'Hangup' and f.Sequence = e.Sequence + 1
 where a.Action = 'KeyPress' and a.NextLocation = 'TransferCSO';

请注意,子查询是缩小候选人范围的原始查询。临时表用于使其快速执行,因为我们可以将它聚集在3列附近。