一条消息定义为2条类型为0的消息之间的所有消息。
我需要在表中找到第一个块 确保所有行都存在于块中
我的解决方案:
SELECT MSG FROM (
SELECT
CASE
WHEN type = 83 AND next_type = 84 THEN REPLACE(CONCAT(MSG,next_msg),' ', '')
WHEN type = 83 AND next_type != 84 THEN MSG
WHEN type = 83 AND next_type IS NULL THEN MSG
, ROW_NUMBER() OVER(order by id) AS row_num
) AS tmp5
WHERE MSG IS NOT NULL
答案 0 :(得分:0)
如果我遵循逻辑,则:
MyCustomTypeCollection
对select concat(msg, (case when next_type = 84 then next_msg else '' end))
from (select m.*,
lead(type) over (order by id) as next_id,
lead(msg) over (order by id) as next_msg,
sum(case when type = 0 then 1 else 0 end) over (order by id) as num_0s
from Messages m
) m
where num0s % 2 = 1 and -- in between two 0s
type = 83;
的计数提供了一种在两个0
之间查找消息的方法。其余的只是对0
进行过滤并进行串联。
答案 1 :(得分:0)
您的方法似乎很好。您首先选择第一个和第二个零类型ID,并且仅对它们之间的ID起作用。但是,我不明白您为什么将ID与它们的相对位置(row_num = id
)进行比较。这迫使您使用表中的所有消息创建一个cross join
,而不是仅仅使用inner join
,exists
子句或between
子句。
这是查询的简化版本,用于批量查询消息:
with limits as
(
select min(id) as id01, max(id) as id02
from (select top 2 id, type from messages where type = 0 order by id) first2
)
select case when next_type = 84 then msg + next_msg else msg end
from
(
select
type, lead(type) over(order by id) as next_type,
msg, lead(msg) over(order by id) as next_msg
from messages m
where id > (select id01 from limits)
and id < (select id02 from limits)
) firstbulk
where type = 83;
您希望messages(type, id)
上的索引可以快速获取零类型ID,而messages(id)
上的索引当然可以快速选择批量中的行。
演示:https://dbfiddle.uk/?rdbms=sqlserver_2017&fiddle=eecb6383b9daa6963e08dde6a0dd30a1
编辑:您希望内置间隙检测。使用COUNT(*)OVER()和零类型ID来查看ID之间是否存在与预期一样多的行。>
with limits as
(
select min(id) as id01, max(id) as id02
from (select top 2 id, type from messages where type = 0 order by id) first2
)
select case when gaps <> 0 then 'Gap detected'
when next_type = 84 then msg + next_msg
else msg end
from
(
select
m.type, lead(m.type) over(order by m.id) as next_type,
m.msg, lead(m.msg) over(order by m.id) as next_msg,
l.id02 - l.id01 - count(*) over () - 1 as gaps
from messages m
join limits l on l.id01 < m.id and l.id02 > m.id
) firstbulk
where type = 83;
演示:https://dbfiddle.uk/?rdbms=sqlserver_2017&fiddle=909228fd2696b419d14cd4a1c2c220a3