0

我需要选择最近 3 个连续状态为Failed或的电话号码Send_Failed。让我用一个例子进一步解释(Microsoft SQL Server)

我的桌子:

| Phone Number Attempted | Date Sent | SMS Return Code |
|*456                    | 2020-11-17|     SEND_FAILED*|
|*456                    | 2020-11-16|     SEND_FAILED*|
|*456                    | 2020-11-15|     FAILED*     |
| 456                    | 2020-11-14|     DELIVERED   |
|*457                    | 2020-11-17|     SEND_FAILED*|
|*457                    | 2020-11-16|     SEND_FAILED*|
|*457                    | 2020-11-15|     SEND_FAILED*|
| 457                    | 2020-11-14|     SEND_FAILED |
| 455                    | 2020-11-17|     DELIVERED   |
| 455                    | 2020-11-16|     FAILED      |
| 455                    | 2020-11-15|     DELIVERED   |
| 455                    | 2020-11-14|     DELIVERED   |
| 454                    | 2020-11-17|     DELIVERED   |
| 454                    | 2020-11-16|     DELIVERED   |
| 454                    | 2020-11-15|     DELIVERED   |
| 454                    | 2020-11-14|     DELIVERED   |
| 453                    | 2020-11-17|     SEND_FAILED |
| 453                    | 2020-11-16|     SEND_FAILED |
| 452                    | 2020-11-17|     SEND_FAILED |
| 452                    | 2020-11-16|     SEND_FAILED |
| 452                    | 2020-11-15|     DELIVERED   |>

预期结果:

456
457

虽然下面的查询它得到的结果非常接近我需要的结果,但它失败了,因为它也选择了记录 452。显然我的查询未能设置三个最近的状态必须是失败的条件。

select 
    i.[Phone Number Attempted], [SMS Return Code]
from 
    (select [Phone Number Attempted], [Date Sent] 
     from [MyTable]) i 
cross apply 
    (select top 3 *  
     from [MyTable] ti 
     where i.[Phone Number Attempted] = ti.[Phone Number Attempted]  
       and ti.[SMS Return Code] != 'DELIVERED') C
group by 
    i.[Phone Number Attempted], [SMS Return Code], C.[Date Sent]
having 
    MIN(C.[SMS Return Code]) !='DELIVERED' 
    and MAX(C.[SMS Return Code]) !='DELIVERED' 
    and count (*) >= 3
    and C.[Date Sent] = MAX(i.[Date Sent])
4

2 回答 2

0

您可以使用lag()

select distinct phone
from (select t.*,
             lag(status) over (partition by phone order by date) as prev_status,
             lag(status, 2) over (partition by phone order by date) as prev2_status,
      from t
     ) t
where status in ('Failed', 'Send_Failed') and
      prev_status in ('Failed', 'Send_Failed') and
      prev2_status in ('Failed', 'Send_Failed') ;
  
于 2020-11-18T03:26:11.843 回答
0

下面的查询为我自己的问题提供了正确的结果

select 
    
      distinct A.[Phone Number Attempted]
     
    

 from 
(
Select  distinct  [Phone Number Attempted],  [SMS Return Code], [Date Sent]

        ,LAG([SMS Return Code]) over (partition by [Phone Number Attempted] order by [Sent Date]) as prev_status
        ,lag([SMS Return Code], 2) over (partition by  [Phone Number Attempted] order by [Sent Date]) as prev2_status

from  [MyTable] ) A 

where 
    prev_status in  ('FAILED', 'SEND_FAILED') and
    prev2_status   in ('FAILED', 'SEND_FAILED') and 
    [SMS Return Code] in ('FAILED', 'SEND_FAILED') and  not exists 
(Select 1 from [MyTable] B where A.[Phone Number Attempted] =B.[Phone Number Attempted] and B.[Sent Date] > A.[Sent Date]) 
于 2020-11-18T07:58:28.843 回答