SQL Server:与组中的下一个X进行比较

时间:2015-05-07 21:59:12

标签: sql-server sql-server-2012

我知道我可以将上一行/下一行与/^'|'$|'(?=,)|(?<=,)'/ # regex used for removing single quote ^' # quote found at start '$ # quote found at end '(?=,) # lookahead, quote followed by a comma (?<=,)' # lookbehind, quote preceded by a comma LAG进行比较,但在我正在进行的比较中;我需要能够偶尔跳过行(但仍需要确认它们)

具体细节:我正在尝试跟踪咨询,以及呼叫环境中的冷热转移。每个呼叫都有一个唯一的密钥,每个阶段都有一个递增的员工编号。它还包含每个呼叫段的开始和结束时间 咨询被定义为在前一个非咨询段结束之前开始和结束的呼叫 热转印是指前一个分段的末尾在前一个分段开始之后,在前一个分段结束之后结束的转移。 冷转移是在上一个分段结束后开始的分段。

示例数据:

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

期望的输出:

LEAD

当前代码,它将每个阶段与以下所有阶段进行比较:

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)  

4 个答案:

答案 0 :(得分:4)

您似乎需要一个子查询来与之前终止的呼叫进行比较。该逻辑假定终止时间对于每个呼叫id是唯一的。

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

答案 1 :(得分:2)

您还可以将MAXOVERROWS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING一起使用,以获取每行前任条目的最长终止时间。

如果您拥有每个条目的最大上次终止时间,则可以按照与当前代码相同的方式进行自我加入。

示例数据

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);

<强>查询

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

答案 2 :(得分:1)

好吧,我想我已经退缩了。

在您的加入条件中,将and ta.empnum<Trans.empnum更改为and ta.empnum+1=Trans.empnum

:d

我用来测试这个代码:

--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

答案 3 :(得分:1)

试试这个。它基本上做了一次滞后来获得咨询,然后放弃它们并再次进行以获得转移,然后组合表格。

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