2015-05-07 14 views
7

So che posso confrontare le righe precedenti/successive con LAG e LEAD, ma nel confronto che sto facendo; Devo essere in grado di saltare le righe occasionalmente (ma devo ancora riconoscerle)Server SQL: confronto con la prossima X nel gruppo

Specifiche: Sto cercando di tenere traccia dei consulti e dei trasferimenti di caldo e freddo in un ambiente di chiamata. Ogni chiamata ha una chiave univoca e un numero di dipendente crescente per ogni fase. Ha anche le ore di inizio e di fine per ogni segmento della chiamata.
Un consulto è definito come una chiamata che inizia e finisce prima che il segmento precedente non consultivo termini.
Un trasferimento a caldo è uno in cui la fine del segmento precedente è dopo l'inizio del segmento precedente e termina dopo la fine del segmento precedente.
Un trasferimento a freddo è un segmento che inizia dopo la fine del segmento precedente.

Esempio Dati:

 
topcallid e_created  e_terminated empnum 
EG995GIFM 16:22:40.933 16:29:51.010 1 
EG995GIFM 16:25:59.827 16:27:49.027 2 
EG995GIFM 16:30:07.453 16:37:44.500 3 
EG995GIFM 16:38:01.677 16:59:30.777 4 
EG995GIFM 16:59:46.737 17:16:48.397 5 
EG995GIFM 17:04:51.243 17:29:21.620 6 

output desiderato:

topcallid.......TransStatus 
EG995GIFM Consult (Stage 1 To 2) 
EG995GIFM Cold Transfer (Stage 1 To 3) 
EG995GIFM Cold Transfer (Stage 3 To 4) 
EG995GIFM Cold Transfer (Stage 4 To 5) 
EG995GIFM Warm Transfer (Stage 5 To 6) 

codice attuale, che dà ogni combinazione si confrontano ogni fase a tutto ciò che segue:

SELECT ta.topcallid, 
     CASE 
      WHEN ta.e_created < Trans.e_created AND ta.e_terminated > Trans.e_terminated THEN 'Consult (Stage ' + CAST(TA.EmpNum AS VARCHAR(3)) + ' To ' + CAST(Trans.EmpNum AS VARCHAR(3)) + ')' 
      WHEN ta.e_terminated < Trans.e_created THEN 'Cold Transfer (Stage ' + CAST(TA.EmpNum AS VARCHAR(3)) + ' To ' + CAST(Trans.EmpNum AS VARCHAR(3)) + ')' 
      WHEN ta.e_terminated > Trans.e_created THEN 'Warm Transfer (Stage ' + CAST(TA.EmpNum AS VARCHAR(3)) + ' To ' + CAST(Trans.EmpNum AS VARCHAR(3)) + ')' 
     END TransStatus 
FROM [TransferTypeAnalysis] TA 
     JOIN [TransferTypeAnalysis] Trans 
      ON TA.topcallid = Trans.topcallid 
       AND ta.empnum < Trans.empnum 
ORDER BY 
     TA.topcallid, 
     ta.empnum 

risposta

4

Sembra che sia necessaria una sottoquery da confrontare con la chiamata terminata precedente. Questa logica presuppone che i tempi terminati siano univoci per ID di chiamata.

select 
    t3.topcallid, 
    case when t3.e_created < t4.e_created and t3.e_terminated > t4.e_terminated then 'Consult (Stage ' + cast(t3.EmpNum as varchar(3)) + ' To ' + cast(t4.EmpNum as varchar(3)) + ')' 
     when t3.e_terminated < t4.e_created then 'Cold Transfer (Stage ' + cast(t3.EmpNum as varchar(3)) + ' To ' + cast(t4.EmpNum as varchar(3)) + ')' 
     when t3.e_terminated > t4.e_created then 'Warm Transfer (Stage ' + cast(t3.EmpNum as varchar(3)) + ' To ' + cast(t4.EmpNum as varchar(3)) + ')' 
     end TransStatus 
from 
    [TransferTypeAnalysis] t3 
    INNER JOIN 
    (
     select 
      t1.topcallid, t1.empnum, t1.e_created, t1.e_terminated, max(t2.e_terminated) previous_term_dt 
     FROM 
      [TransferTypeAnalysis] t1 
      left join [TransferTypeAnalysis] t2 
      on t1.topcallid=t2.topcallid and t1.empnum>t2.empnum 
     GROUP BY t1.topcallid, t1.empnum, t1.e_created, t1.e_terminated 
    ) as t4 on t3.topcallid = t4.topcallid and t3.e_terminated = t4.previous_term_dt 
+0

Non so perché, ma la linea di casi di trasferimento a freddo viene troncata dalla formattazione del codice, non ho modificato la logica del caso, quindi è possibile utilizzare il codice originale – trouta

+0

StackExchange piace pensare di utilizzare HTML in risponde in modo che possa cancellare intere sezioni come un comando html sconosciuto – SeanC

+0

funziona in modo fantastico. Grazie – SeanC

1

Beh, credo Ti ho dato le spalle a questo.

Nelle vostre condizioni di join, modificare and ta.empnum<Trans.empnum-and ta.empnum+1=Trans.empnum

: D

codice che ho usato per testare questo:

--CREATE TABLE #TMP (topcallid varchar(15), e_created time, e_terminated time, empnum int) 
--INSERT INTO #TMP VALUES ('EG995GIFM', '16:22:40.933', '16:29:51.010', 1) 
--INSERT INTO #TMP VALUES ('EG995GIFM', '16:25:59.827', '16:27:49.027', 2) 
--INSERT INTO #TMP VALUES ('EG995GIFM', '16:30:07.453', '16:37:44.500', 3) 
--INSERT INTO #TMP VALUES ('EG995GIFM', '16:38:01.677', '16:59:30.777', 4) 
--INSERT INTO #TMP VALUES ('EG995GIFM', '16:59:46.737', '17:16:48.397', 5) 
--INSERT INTO #TMP VALUES ('EG995GIFM', '17:04:51.243', '17:29:21.620', 6) 

select ta.topcallid, 
    case when ta.e_created<Trans.e_created and ta.e_terminated>Trans.e_terminated then 'Consult (Stage ' + cast(TA.EmpNum as varchar(3)) + ' To ' + cast(Trans.EmpNum as varchar(3)) + ')' 
     when ta.e_terminated<Trans.e_created then 'Cold Transfer (Stage ' + cast(TA.EmpNum as varchar(3)) + ' To ' + cast(Trans.EmpNum as varchar(3)) + ')' 
     when ta.e_terminated>Trans.e_created then 'Warm Transfer (Stage ' + cast(TA.EmpNum as varchar(3)) + ' To ' + cast(Trans.EmpNum as varchar(3)) + ')' 
     end TransStatus 
FROM #TMP TA 
join #TMP Trans 
    on TA.topcallid=Trans.topcallid 
    and ta.empnum+1=Trans.empnum 

order by TA.topcallid,ta.empnum 
+0

+1 si unirà il prossimo (che è quello che 'LEAD' avrebbe fatto, ma, se si guarda l'output desiderato, ha 1 -> 3 (dato che 2 è riportato ma non fa parte della catena di trasferimento) – SeanC

+0

Ah! Scusa, non l'ho capito. Cercherò di dare una mano stasera quando tornerò a casa dal lavoro. :) Per chiarire, si desidera saltare 2 nella sequenza (se questa è la parola giusta) ma riconoscerla come una consultazione. E questo perché l'empnum 1 termina DOPO l'empnum2 terminato? –

+0

sì, è corretto – SeanC

1

Prova questa. Fondamentalmente fa il ritardo una volta per ottenere i consulti, quindi li abbandona e lo fa di nuovo per ottenere i trasferimenti, quindi combina le tabelle.

SELECT * 
,CASE 
    WHEN lag(e_terminated) OVER (
      PARTITION BY topcallID ORDER BY e_created 
      ) IS NULL 
     THEN NULL 
    WHEN lag(e_terminated) OVER (
      PARTITION BY topcallID ORDER BY e_created 
      ) > e_terminated 
     THEN 'Consult ' + cast(lag(EmpNum) OVER (
        PARTITION BY topcallID ORDER BY e_created 
        ) AS VARCHAR) + ' to ' + cast(empnum AS VARCHAR) 
    WHEN lag(e_terminated) OVER (
      PARTITION BY topcallID ORDER BY e_created 
      ) < e_created 
     THEN 'Cold Transfer ' + cast(lag(EmpNum) OVER (
        PARTITION BY topcallID ORDER BY e_created 
        ) AS VARCHAR) + ' to ' + cast(empnum AS VARCHAR) 
    ELSE 'Warm Transfer ' + cast(lag(EmpNum) OVER (
       PARTITION BY topcallID ORDER BY e_created 
       ) AS VARCHAR) + ' to ' + cast(empnum AS VARCHAR) 
    END AS StatusTemp 
INTO #temp1 
FROM MyTable 

SELECT a.topcallID 
,coalesce(b.StatusTemp2, a.StatusTemp) AS TransStatus 
FROM #temp1 a 
LEFT JOIN (
SELECT * 
    ,CASE 
     WHEN lag(e_terminated) OVER (
       PARTITION BY topcallID ORDER BY e_created 
       ) IS NULL 
      THEN NULL 
     WHEN lag(e_terminated) OVER (
       PARTITION BY topcallID ORDER BY e_created 
       ) > e_terminated 
      THEN 'Consult ' + cast(lag(EmpNum) OVER (
         PARTITION BY topcallID  ORDER BY e_created 
         ) AS VARCHAR) + ' to ' + cast(empnum AS VARCHAR) 
     WHEN lag(e_terminated) OVER (
       PARTITION BY topcallID ORDER BY e_created 
       ) < e_created 
      THEN 'Cold Transfer ' + cast(lag(EmpNum) OVER (
         PARTITION BY topcallID ORDER BY e_created 
         ) AS VARCHAR) + ' to ' + cast(empnum AS VARCHAR) 
     ELSE 'Warm Transfer ' + cast(lag(EmpNum) OVER (
        PARTITION BY topcallID ORDER BY e_created 
        ) AS VARCHAR) + ' to ' + cast(empnum AS VARCHAR) 
     END AS StatusTemp2 
FROM #temp1 
WHERE StatusTemp NOT LIKE 'Consult%' 
    OR StatusTemp IS NULL 
) b 
ON a.empNum = b.empnum 
    AND a.topcallID = b.topCallID 
where coalesce(b.StatusTemp2, a.StatusTemp) is not null 
2

È anche possibile utilizzare MAX con OVER e ROWS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING per ottenere il tempo massimo di una voce precedente per ogni riga terminata.

Una volta terminato il tempo massimo precedente per ciascuna voce, è possibile eseguire l'auto join nello stesso modo in cui si esegue il codice corrente.

dei dati di campionamento

DECLARE @TransferTypeAnalysis TABLE (topcallid VARCHAR(20),e_created TIME,e_terminated TIME,empnum INT) 

insert into @TransferTypeAnalysis 
VALUES('EG995GIFM', '16:22:40.933', '16:29:51.010', 1), 
('EG995GIFM', '16:25:59.827', '16:27:49.027', 2), 
('EG995GIFM', '16:30:07.453', '16:37:44.500', 3), 
('EG995GIFM', '16:38:01.677', '16:59:30.777', 4), 
('EG995GIFM', '16:59:46.737', '17:16:48.397', 5), 
('EG995GIFM', '17:04:51.243', '17:29:21.620', 6); 

query

SELECT ta.topcallid, 
    CASE WHEN TA_Prev.e_created<TA.e_created and TA_Prev.e_terminated>TA.e_terminated THEN 'Consult' 
     WHEN TA_Prev.e_terminated<TA.e_created THEN 'Cold Transfer' 
     WHEN TA_Prev.e_terminated>TA.e_created THEN 'Warm Transfer' 
     END + ' (Stage '+ cast(TA_Prev.EmpNum AS VARCHAR(3)) + ' To ' + cast(TA.EmpNum AS VARCHAR(3)) + ')'TransStatus 
FROM 
(
SELECT *,MAX(e_terminated)OVER(PARTITION BY topcallid ORDER BY empnum ROWS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING) as max_term 
FROM @TransferTypeAnalysis 
)TA 
INNER JOIN @TransferTypeAnalysis TA_Prev 
ON TA.topcallid = TA_Prev.topcallid AND TA.max_term = TA_Prev.e_terminated AND TA.empnum > TA_Prev.empnum 

SQL Fiddle