在oracle SQL中搜索模式的出现

时间:2018-03-29 06:05:03

标签: sql oracle

问题:在一系列数字中说4,2,3,6,5,1,3,4,2我正在寻找特定模式的出现再次为低和低。在这个例子中 结果应该是2个数字序列, 第一个是2,3,6,5,1,另一个是3,4,2 逻辑是: 4< 2 No 2< 3是3< 6 No 6< 5 No 5< 1 No 1< 3是(基本上寻找一系列倍数(Yes's No's和Yes's) 和 3< 4是和4< 2否(如果最后一个是没有主持是,那么它也是匹配) 任何帮助都将受到高度赞赏。谢谢。

1 个答案:

答案 0 :(得分:0)

使用LAGLEAD查看序列中的上一个/下一个值,然后计算序列值中的变化率和加速率,以查找序列中的最小值和这些行之间的聚合:

SQL Fiddle

查询1

WITH your_data ( id, value ) AS (
  SELECT ROWNUM,
         COLUMN_VALUE
  FROM   TABLE( SYS.ODCINUMBERLIST( 4,2,3,6,5,1,3,4,2 ) )
),
changes( id, value, gradient, acceleration ) AS (
  SELECT id,
         value,
         CASE
           WHEN nxt IS NULL THEN prv
           WHEN prv IS NULL THEN nxt
           WHEN prv = -nxt THEN 0
           WHEN nxt = 0    THEN prv
           WHEN prv = 0    THEN nxt
           ELSE nxt
         END,
         CASE
           WHEN nxt IS NULL THEN COALESCE( prv, 0 )
           WHEN prv IS NULL THEN nxt
           WHEN prv =  1 AND nxt IN (0,-1) THEN -1
           WHEN prv = -1 AND nxt IN (0, 1) THEN  1
           ELSE 0
         END
  FROM   (
    SELECT id,
           value,
           SIGN( value - LAG( value ) OVER ( ORDER BY id )  ) AS prv,
           SIGN( LEAD( value ) OVER ( ORDER BY id ) - value ) AS nxt
    FROM   your_data
  )
),
minima ( id, value, gradient, acceleration, last_minima, next_minima ) AS (
  SELECT id,
         value,
         gradient,
         acceleration,
         LAST_VALUE(  CASE WHEN acceleration = 1 THEN id END ) IGNORE NULLS
           OVER ( ORDER BY id ROWS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING ),
         FIRST_VALUE( CASE WHEN acceleration = 1 THEN id END ) IGNORE NULLS
           OVER ( ORDER BY id ROWS BETWEEN 1 FOLLOWING AND UNBOUNDED FOLLOWING )
  FROM   changes
  ORDER BY id
)
SELECT ( SELECT LISTAGG( value, ',' ) WITHIN GROUP ( ORDER BY id )
         FROM   minima n
         WHERE  ( m.last_minima IS NULL OR m.last_minima <= n.id )
         AND    ( m.next_minima IS NULL OR m.next_minima >= n.id )
       ) As range
FROM   minima m
WHERE  gradient = 0
AND    acceleration = -1

<强> Results

|     RANGE |
|-----------|
| 2,3,6,5,1 |
|   1,3,4,2 |

(注意:序列中连续相等的值未经测试)