问题描述
我有两个表prod_replay_in
和prod_replay_out
如下。
对于msg_type
表中CDST010的prod_replay_in
,在prod_replay_out
表中确认为CDST01C
。 msg_type
与CDST100相同,它在prod_replay_out
表中的确认消息为CDST10C
。在下表中,cdsx_time
很重要。例如,第二条CDST100消息将基于CDST10C
具有第二条cdsx_time
消息。
注意:2个表之间的联接基于cdsx_id
,因为这在两个表之间是常见的。 CDST010和CDST01C
在cdsx_id
和prod_replay_in
表中分别只有相同的prod_replay_out
的一个条目。另外,CDST100和CDST10C
消息的数量根据cdsx_id
的不同而变化。
我要搜索什么?
我要按照以下条件在prod_replay_in
表中搜索CDST100消息的数量:
- 如果CDST100的
bancs_msg
中的第四个字符与CDST01C的msg_body
中的第四个字符相匹配,则获取第一个CDST100。 - 如果CDST100的
bancs_msg
中的第四个字符与第四个字符匹配,则获得第二个CDST100 第一个CDST10C的msg_body
中的字符 - 如果bancs_msg中CDST100的第四个字符与第四个字符匹配,则获取第三个CDST100
在
msg_body
中获得第二个CDST10C
以上模式类似于检查带有第一CDST10C的第二CDST100,检查带有第二CDST10C的第三CDST100,等等。
prod_replay_in
id(serial) | msg_type(varchar) | cdsx_time(timestamp) | cdsx_id(varchar) | bancs_msg(text)
------------------------------------------------------------------------------------------
8334698 | CDST010 | 2020-02-24 14:23:01.0 | T202005518525 | ABCD
8341809 | CDST100 | 2020-02-24 14:47:38.0 | T202005518525 | ANOC
8342732 | CDST100 | 2020-02-24 14:51:53.0 | T202005518525 | PHLM
8344890 | CDST100 | 2020-02-24 15:15:14.0 | T202005518525 | JKQO
prod_replay_out
id(serial) | msg_type(varchar) | cdsx_time(timestamp) | cdsx_id(varchar) | msg_body(text)
------------------------------------------------------------------------------------------
42164527 | CDST01C | 2020-02-24 14:23:08.016 | T202005518525 | AQRS
42176068 | CDST10C | 2020-02-24 14:47:47.056 | T202005518525 | STUM
42177522 | CDST10C | 2020-02-24 14:52:00.031 | T202005518525 | XYZK
42245814 | CDST10C | 2020-02-24 15:30:00.045 | T202005518525 | ASQO
我尝试了什么?
我尝试创建用于匹配第一个CDST100和CDST01C的SQL查询,但不确定如何与带有CDST10C的后续CDST100进行比较?
SELECT count(T.id) FROM prod_replay_in T JOIN prod_replay_out O ON T.CDSX_ID = O.CDSX_ID
JOIN prod_replay_out K ON K.CDSX_ID = O.CDSX_ID
WHERE T.MSG_TYPE = 'CDST100'
and O.msg_type = 'CDST01C'
and K.msg_type = 'CDST10C'
and ( (
min(T.cdsx_time) > O.cdsx_time
and substr(T.bancs_msg,4,1) = substr(O.msg_body,1)
)
);
解决方法
我尝试了以下代码。据我所知,它应该工作。请随时建议是否缺少任何情况。
Select count(T.*) from PROD_REPLAY_IN T,PROD_REPLAY_OUT O
Where T.msg_type = 'CDST100'
AND O.msg_type IN ('CDST01C','CDST10C')
AND T.cdsx_id = O.cdsx_id
AND substr(T.bancs_msg,4,1) = substr(O.msg_body,1)
AND (O.cdsx_id,O.cdsx_time) IN (Select Y.cdsx_id,Max(Y.cdsx_time) from PROD_REPLAY_OUT Y
Where Y.msg_type IN ('CDST01C','CDST10C')
AND O.cdsx_id = Y.cdsx_id
AND T.cdsx_time > Y.cdsx_time
GROUP BY Y.cdsx_id
)
,
只要您知道按时间戳记,每prod_replay_out
行将有一个对应的prod_replay_in
行,您可以将其设置为使用窗口函数来回避开头的不同消息类型。重播:
with interleave as (
select msg_type,cdsx_time,cdsx_id,bancs_msg as msg,'in' as direction
from prod_replay_in
union all
select msg_type,msg_body as msg,'out' as direction
from prod_replay_out
),match_cdst100 as (
select cdsx_id,msg,lag(msg) over (partition by cdsx_id
order by cdsx_time) as last_msg
from interleave
where msg_type = 'CDST100'
)
select cdsx_id,count(*)
from match_cdst100
where substr(msg,1) = substr(last_msg,1)
group by cdsx_id;