如何根据前面和后面的行中的值筛选出行?

ercv8c1e  于 2022-09-18  发布在  Java
关注(0)|答案(3)|浏览(177)

我正在寻找一种方法来过滤掉MS SQL查询中某个范围内的数据。在本例中,“Test2”是我的起点,“Test4”是我的终点。我想过滤掉“Test1”,只要它在“Test2”和“Test4”行之间。如果它在外面,那么我想留着它。我还想把“测试3”排成一行。

实际结果:
DateTime|消息

2022-09-09 00:00|测试1
2022-09-09 01:00|测试2
2022-09-09 02:00|测试1
2022-09-09 03:00|测试1
2022-09-09 04:00|测试3
2022-09-09 05:00|测试4

预期结果:

DateTime|消息

2022-09-09 00:00|测试1
2022-09-09 01:00|测试2
2022-09-09 04:00|测试3
2022-09-09 05:00|测试4

第二个例子

实际结果:
DateTime|消息

2022-09-08 11:00|测试3
2022-09-08 12:00|测试1
2022-09-09 01:00|测试2
2022-09-09 02:00|测试1
2022-09-09 03:00|测试1
2022-09-09 04:00|测试3
2022-09-09 05:00|测试4

预期结果:

DateTime|消息

2022-09-08 11:00|测试3
2022-09-08 12:00|测试1
2022-09-09 01:00|测试2
2022-09-09 04:00|测试3
2022-09-09 05:00|测试4

第三个例子

实际结果:
DateTime|消息

2022-09-08 11:00|测试3
2022-09-08 12:00|测试1
2022-09-09 01:00|测试2
2022-09-09 02:00|测试1
2022-09-09 03:00|测试1
2022-09-09 04:00|测试3
2022-09-09 05:00|测试4
2022-09-09 06:00|测试1

预期结果:

DateTime|消息

2022-09-08 11:00|测试3
2022-09-08 12:00|测试1
2022-09-09 01:00|测试2
2022-09-09 04:00|测试3
2022-09-09 05:00|测试4
2022-09-09 06:00|测试1

任何帮助我们都将不胜感激。

已解决:

多亏了@Ahmed提供的问题,我设法解决了这个问题。感谢花时间解决这个问题的每一个人。

谢谢!

wmtdaxz3

wmtdaxz31#

您可以尝试以下操作:

WITH CTE AS
(
  SELECT D.[DateTime], D.Message, SUM(D.F) OVER (ORDER BY [DateTime]) FLAG
  FROM
  (
    SELECT *,CASE WHEN Message ='Test2' OR Message='Test4' THEN 1 ELSE 0 END AS F
    FROM table_name
  ) D
)
SELECT [DateTime], Message FROM CTE T 
WHERE(
        NOT EXISTS(SELECT 1 FROM CTE D WHERE D.MESSAGE='Test2' AND D.FLAG=T.FLAG)
        AND NOT EXISTS(SELECT 1 FROM CTE D WHERE D.MESSAGE='Test4' AND D.FLAG=T.FLAG+1)
        AND T.MESSAGE='Test1'
     ) 
     OR T.MESSAGE <> 'Test1'
     OR T.FLAG = 0

此查询将过滤掉‘Test2’和‘Test4’之间的所有‘Test1’值,但不会过滤掉‘Test4’和‘Test2’之间的所有值,这是根据您的要求而定的;“‘Test2’是我的起点,‘Test4’是我的终点”。

请参见demo

xxhby3vn

xxhby3vn2#

我尝试了这个查询,我可以执行它:,

WITH cte AS (
    SELECT
        datetime,
        message
    FROM
        mytable
    WHERE
        datetime >= ( SELECT TOP 1 datetime d1 FROM mytable WHERE message = 'Test2' ) 
        AND
        datetime <= ( SELECT TOP 1 datetime d2 FROM mytable WHERE message = 'Test4' )
        AND
        message = 'Test1'
)
SELECT
    mt.datetime,
    mt.message
FROM
    mytable mt
    LEFT OUTER JOIN cte ON
        mt.datetime = cte.datetime
        AND
        mt.message = cte.message
WHERE
    cte.datetime IS NULL
    AND
    cte.message IS NULL

(我是第一次接触堆栈溢出;如果代码中有任何错误或不是正确的方式,我希望收到反馈)。

2ekbmq32

2ekbmq323#

select  DateTime
       ,last_group as Message
from    (
        select *
               ,case when Message = 'Test1' and start_end = 1 then null else Message end as last_group 
        from   (
                select * 
                       ,count(case when Message = 'Test2' then 1 when Message = 'Test4' then 1 end) over(order by DateTime) as start_end
                from t
               ) t
         ) t
where    last_group is not null

DateTime|消息

2022-09-09 00:00:00.000|测试1
2022-09-09 01:00:00.000|测试2
2022-09-09 04:00:00.000|测试3
2022-09-09 05:00:00.000|测试4
2022-09-09 06:00:00.000|测试1

Fiddle

相关问题