从分组结果中的多行中选择数据

时间:2018-09-14 08:08:18

标签: sql-server tsql

我遇到了一个TSQL问题,我有一些分组结果,并且需要组成分组结果的每一行中的一些数据,理想情况下-我希望第一行中的收件人为'HuntGroup,收件人为第二行为“收件人”。

分组结果中可能有1或2行,所以我只需要2行中的结果。有一个CorrelationCode可以将两条记录联系在一起-一行将包含寻线组信息,另一行将具有应答用户。

如果要测试,可以从下面的数据生成:

CREATE TABLE #phone_calls
(
    Caller VARCHAR(200),
    Recipient VARCHAR(200),
    CorrelationCode VARCHAR(200),
    StartTime VARCHAR(200),
    EndTime VARCHAR(200),
);

INSERT INTO #phone_calls(Caller, Recipient, CorrelationCode, StartTime, EndTime)
VALUES 
    ( 'user159', 'huntgroup1',  'AEF4562JJH',   DATEADD(mi, -60,GETDATE()), DATEADD(mi, -60, GETDATE()) ),
    ( 'user159', 'user10',      'AEF4562JJH',   DATEADD(mi, -59,GETDATE()), DATEADD(mi, -56, GETDATE()) ),
    ( 'user11', 'huntgroup2',   'OSJEJDJE883',  DATEADD(mi, -58,GETDATE()), DATEADD(mi, -58, GETDATE()) ),
    ( 'user11', 'user5',        'OSJEJDJE883',  DATEADD(mi, -57,GETDATE()), DATEADD(mi, -56, GETDATE()) ),
    ( 'user449', 'huntgroup1',  'SHEJJSMM27',   DATEADD(mi, -56,GETDATE()), DATEADD(mi, -56, GETDATE()) ),
    ( 'user449', 'user91',      'SHEJJSMM27',   DATEADD(mi, -55,GETDATE()), DATEADD(mi, -54, GETDATE()) ),
    ( 'user128', 'huntgroup1',  'USJEHHS45461', DATEADD(mi, -54,GETDATE()), DATEADD(mi, -54, GETDATE()) ),
    ( 'user128', 'user46',      'USJEHHS45461', DATEADD(mi, -53,GETDATE()), DATEADD(mi, -46, GETDATE()) ),
    ( 'user120', 'huntgroup1',  'SEES45646',    DATEADD(mi, -52,GETDATE()), DATEADD(mi, -52, GETDATE()) ),
    ( 'user120', 'user5',       'SEES45646',    DATEADD(mi, -51,GETDATE()), DATEADD(mi, -49, GETDATE()) ),
    ( 'user316', 'huntgroup1',  'LLLS45646',    DATEADD(mi, -50,GETDATE()), DATEADD(mi, -50, GETDATE()) ),
    ( 'user316', 'user5',       'LLLS45646',    DATEADD(mi, -49,GETDATE()), DATEADD(mi, -49, GETDATE()) ),
    ( 'user19', 'huntgroup1',   'YHJASA434',    DATEADD(mi, -48,GETDATE()), DATEADD(mi, -48, GETDATE()) ),
    ( 'user202', 'huntgroup1',  '78RTGDHDG',    DATEADD(mi, -47,GETDATE()), DATEADD(mi, -47, GETDATE()) ),
    ( 'user141', 'huntgroup2',  'CFGBN1231',    DATEADD(mi, -46,GETDATE()), DATEADD(mi, -46, GETDATE()) ),
    ( 'user168', 'huntgroup1',  'KKLDJ5463',    DATEADD(mi, -45,GETDATE()), DATEADD(mi, -45, GETDATE()) ),
    ( 'user168', 'user91',      'KKLDJ5463',    DATEADD(mi, -44,GETDATE()), DATEADD(mi, -40, GETDATE()) );

SELECT *将得到以下结果:

Caller      Recipient   CorrelationCode StartTime       EndTime
user159     huntgroup1  AEF4562JJH  Sep 13 2018  3:56PM Sep 13 2018  3:56PM
user159     user10      AEF4562JJH  Sep 13 2018  3:57PM Sep 13 2018  4:00PM
user11      huntgroup2  OSJEJDJE883 Sep 13 2018  3:58PM Sep 13 2018  3:58PM
user11      user5       OSJEJDJE883 Sep 13 2018  3:59PM Sep 13 2018  4:00PM
user449     huntgroup1  SHEJJSMM27  Sep 13 2018  4:00PM Sep 13 2018  4:00PM
user449     user91      SHEJJSMM27  Sep 13 2018  4:01PM Sep 13 2018  4:02PM
user128     huntgroup1  USJEHHS45461    Sep 13 2018  4:02PM Sep 13 2018  4:02PM
user128     user46      USJEHHS45461    Sep 13 2018  4:03PM Sep 13 2018  4:10PM
user120     huntgroup1  SEES45646   Sep 13 2018  4:04PM Sep 13 2018  4:04PM
user120     user5       SEES45646   Sep 13 2018  4:05PM Sep 13 2018  4:07PM
user316     huntgroup1  LLLS45646   Sep 13 2018  4:06PM Sep 13 2018  4:06PM
user316     user5       LLLS45646   Sep 13 2018  4:07PM Sep 13 2018  4:07PM
user19      huntgroup1  YHJASA434   Sep 13 2018  4:08PM Sep 13 2018  4:08PM
user202     huntgroup1  78RTGDHDG   Sep 13 2018  4:09PM Sep 13 2018  4:09PM
user141     huntgroup2  CFGBN1231   Sep 13 2018  4:10PM Sep 13 2018  4:10PM
user168     huntgroup1  KKLDJ5463   Sep 13 2018  4:11PM Sep 13 2018  4:11PM
user168     user91      KKLDJ5463   Sep 13 2018  4:12PM Sep 13 2018  4:16PM

我要获取的结果集中是:

Caller      HuntGroup   Recipient   CorrelationCode StartTime       EndTime
user159     huntgroup1  user10      AEF4562JJH  Sep 13 2018  3:56PM Sep 13 2018  4:00PM
user168     huntgroup1  user91      KKLDJ5463   Sep 13 2018  4:11PM Sep 13 2018  4:16PM
user316     huntgroup1  user5       LLLS45646   Sep 13 2018  4:06PM Sep 13 2018  4:07PM
user11      huntgroup2  user5       OSJEJDJE883 Sep 13 2018  3:58PM Sep 13 2018  4:00PM
user120     huntgroup1  user5       SEES45646   Sep 13 2018  4:04PM Sep 13 2018  4:07PM
user449     huntgroup1  user91      SHEJJSMM27  Sep 13 2018  4:00PM Sep 13 2018  4:02PM
user128     huntgroup1  user46      USJEHHS45461    Sep 13 2018  4:02PM Sep 13 2018  4:10PM

我可以使用下面的SQL来实现这一点,但是自然这是行不通的,因为它依赖于使用MIN和MAX(Recipient),因此行不通。

 SELECT 
    MIN(Caller) Caller, 
    MIN(Recipient) HuntGroup, 
    MAX(Recipient) Recipient, 
    MIN(CorrelationCode) CorrelationCode, 
    MIN(StartTime) StartTime, 
    MAX(EndTime) EndTime 
FROM 
(
    SELECT 
         1 AS 'NumAnswers', Caller, Recipient, CorrelationCode, StartTime, EndTime
    FROM #phone_calls
) c 
GROUP BY c.CorrelationCode
HAVING SUM(NumAnswers) > 1

我也玩过; WTE,但我经验不足,无法从中获得两个价值

;WITH cte AS 
(
  SELECT Caller, Recipient AS 'HuntGroup', Recipient, CorrelationCode, StartTime, EndTime,
         ROW_NUMBER() OVER (PARTITION BY CorrelationCode ORDER BY Recipient) rn
  FROM #phone_calls
)

SELECT * FROM cte
WHERE rn = 2

因此,如果有任何可以提供解决方案的TSQL专家,将不胜感激。

1 个答案:

答案 0 :(得分:2)

美好的一天,

请检查以下解决方案之一是否满足您的需求(我使用表格phone_calls代替#phone_calls):

-- Option 1
;with MyCTE as (
    select 
        [Caller], Recipient, CorrelationCode, StartTime, EndTime
        ,RN = ROW_NUMBER() over (partition by [Caller], CorrelationCode order by StartTime, EndTime)
    from phone_calls
)
,MyCTE2 as (
    select RN, [Caller], Recipient as HuntGroup, null as Recipient, CorrelationCode, StartTime, null as EndTime
    from MyCTE
    where RN = 1
    union all
    select RN, [Caller], null as HuntGroup, Recipient, CorrelationCode, null as StartTime, EndTime
    from MyCTE
    where RN = 2
)
select [Caller],MAX(HuntGroup),MAX(Recipient),CorrelationCode,MAX(StartTime),MAX(EndTime)
from MyCTE2
group by [Caller], CorrelationCode
having max(RN) > 1
GO


-- Option 2:
;with MyCTE as (
    select 
        [Caller], Recipient, CorrelationCode, StartTime, EndTime
        ,RN = ROW_NUMBER() over (partition by [Caller], CorrelationCode order by StartTime, EndTime)
    from phone_calls
)
,MyCTE1 as (
    select RN, [Caller], Recipient, CorrelationCode, StartTime, EndTime
    from MyCTE
    where RN = 1
)
,MyCTE2 as (
    select RN, [Caller], Recipient, CorrelationCode, StartTime, EndTime
    from MyCTE
    where RN = 2
)
SELECT 
    t1.Caller, t1.Recipient as HuntGroup, t2.Recipient, t1.CorrelationCode, 
    t1.StartTime, t2.EndTime
from MyCTE1 t1
LEFT JOIN MyCTE2 t2 ON t1.Caller = t2.Caller and t1.CorrelationCode = t2.CorrelationCode
where not t2.Caller IS NULL