【问题标题】:Search sequence pattern in SQL ServerSQL Server 中的搜索序列模式
【发布时间】:2020-05-05 04:25:36
【问题描述】:

我有这样的记录,我想在 SQL Server 中按模式和序列(如 (50,54,50))在值字段中搜索它应该返回 02,03,04 任何人都知道这样做。

======================================
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
======================================

【问题讨论】:

  • 你试过什么?你在哪里卡住了?
  • 请为您的逻辑和要求添加更多解释,
  • 看起来 IN 子句可以满足您的需求。

标签: sql sql-server database tsql


【解决方案1】:

用户语音网站Add support for Row Pattern Recognition in T-SQL (SQL:2016 features R010 and 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

【讨论】:

  • where子句中的序列过长是不可能的。
  • 那么你要匹配多长时间的序列?
  • @MartinSmith 。 . .我宁愿看到对数组的全面支持,它也可以用于此。
【解决方案2】:

如果您想要更灵活的方法,可以使用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';

Here 是一个 dbfiddle。

如果支持 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';

但可惜不是。

【讨论】:

  • 是的,我也考虑过string_agg。他们可能只是string_agg 整个批次并使用正则表达式根据序列可能覆盖的行数来查找他们的模式
【解决方案3】:

如果我的要求正确,你可以试试下面在 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

【讨论】:

  • where子句中的序列过长是不可能的。
  • 请提及最坏的可能性。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-02-12
  • 1970-01-01
  • 2013-08-05
  • 2011-04-15
  • 1970-01-01
  • 2011-07-23
  • 1970-01-01
相关资源
最近更新 更多