Шаблон последовательности поиска на SQL сервере - PullRequest
0 голосов
/ 05 мая 2020
• 1000 1001 *
======================================
Id             Date             Value
01             2020-01-01       50
02             2020-01-02       50
03             2020-01-03       54
04             2020-01-04       50
05             2020-01-05       35
06             2020-01-06       98
07             2020-01-07       13
======================================

Ответы [ 3 ]

3 голосов
/ 05 мая 2020

На сайте голосовой почты пользователя есть запрос Добавить поддержку для распознавания образов строк в T- SQL (SQL: 2016 включает R010 и R020) , что, как мне кажется, позволит это сделать.

А пока это должно делать то, что вам нужно

WITH T AS
(
SELECT *, 
       LAG(Id) OVER (ORDER BY Id) AS PrevId, 
       LAG(value) OVER (ORDER BY Id) AS PrevValue,
       LEAD(Id) OVER (ORDER BY Id) AS NextId, 
       LEAD(value) OVER (ORDER BY Id) AS NextValue
FROM YourTable
)
SELECT PrevId, Id, NextId
FROM T
WHERE PrevValue = 50 AND Value =54 AND NextValue = 50
3 голосов
/ 05 мая 2020

Если вам нужен более гибкий подход, вы можете использовать cross apply:

select t2.*
from t cross apply
     (select string_agg(id, ',') within group (order by date) as ids,
             string_agg(value, ',') within group (order by date) as vals
      from (select top (3) t2.*
            from t t2
            where t2.date >= t.date
            order by t2.date
           ) t2
     ) t2
where vals = '50,54,50';

Здесь - скрипт db <>.

If string_agg() поддерживались как оконные функции, вы могли использовать:

select t.*
from (select t.*,
             string_agg(id, ',') within group (order by date) over (order by id rows between current row and 2 following) as ids,
             string_agg(value, ',') within group (order by date) over (order by id rows between current row and 2 following) as vals
      from t
     ) t
where vals = '50,54,50';

Но, увы, это не так.

1 голос
/ 05 мая 2020

Если я правильно понял ваши требования, вы можете попробовать это ниже logi c, разработанный с помощью LAG и LEAD-

DEMO HERE

WITH CTE
AS
(
    SELECT Id,Date,
    LAG(value,2) OVER(ORDER BY id) lag_2,
    LAG(value,1) OVER(ORDER BY id) lag_1,
    Value c_val,
    LEAD(value,1) OVER(ORDER BY id) lead_1,
    LEAD(value,2) OVER(ORDER BY id) lead_2
    FROM your_table
)

SELECT Id,Date,
CASE 
    WHEN (lag_2 = 50 AND lag_1 = 54 AND c_val = 50) OR
         (lag_1 = 50 AND c_val = 54 AND lead_1 = 50) OR
         (c_val = 50 AND lead_1 = 54 AND lead_2 = 50)
         THEN (
             CASE 
                 WHEN lead_1 = 54 THEN 02
                 WHEN c_val = 54 THEN 03
                 WHEN lag_1 = 54 THEN 04
             END
         )
    ELSE c_val
END
FROM CTE
...