如何识别 SQL 中的模式

How to identify pattern in SQL

这是我的table。它确实由 A、B 和 C 列组成。一次只有一列值为真。

我的任务是根据最近的五行来识别模式。 例如

我需要搜索整个 table 以查找这五个值何时重复。

如果重复,这些模式的下一个可用值是多少,并显示在该模式之后找到 A、B 和 C 值的次数。

如何在 SQL 中完成此操作?我正在使用甲骨文 11g。谢谢

您可以将 a, b, c 值转换为一个三进制数,然后计算该行和前 4 行的值,就好像这些行的三进制值包含一个 5 位数的三进制数,然后使用解析查找下一次出现并计算出现次数的函数:

SELECT id,
       a,
       b,
       c,
       CASE
       WHEN grp_value IS NULL
       THEN NULL
       ELSE MIN(id) OVER (
              PARTITION BY grp_value
              ORDER     BY id
              ROWS BETWEEN 1 FOLLOWING AND UNBOUNDED FOLLOWING
            ) + 1
       END  AS row_after_next_match,
       CASE
       WHEN grp_value IS NULL
       THEN 0
       ELSE COUNT(id) OVER ( PARTITION BY grp_value )
       END  AS num_matches
FROM   (
  SELECT id,
         a,
         b,
         c,
         value,
         81 * LAG(value,4) OVER ( ORDER BY id ) +
         27 * LAG(value,3) OVER ( ORDER BY id ) +
          9 * LAG(value,2) OVER ( ORDER BY id ) +
          3 * LAG(value,1) OVER ( ORDER BY id ) +
          1 * value AS grp_value
  FROM   (
    SELECT id,
           a,
           b,
           c,
           DECODE(1,a,0,b,1,c,2) AS value
    FROM   table_name
  )
)
ORDER BY id

其中,对于示例数据:

CREATE TABLE table_name (
  id PRIMARY KEY,
  a,
  b,
  c,
  CHECK (a IN (0,1)),
  CHECK (b IN (0,1)),
  CHECK (c IN (0,1)),
  CHECK (a+b+c = 1)
) AS
SELECT  1, 1, 0, 0 FROM DUAL UNION ALL
SELECT  2, 1, 0, 0 FROM DUAL UNION ALL
SELECT  3, 0, 1, 0 FROM DUAL UNION ALL
SELECT  4, 1, 0, 0 FROM DUAL UNION ALL
SELECT  5, 0, 1, 0 FROM DUAL UNION ALL
SELECT  6, 0, 0, 1 FROM DUAL UNION ALL
SELECT  7, 1, 0, 0 FROM DUAL UNION ALL
SELECT  8, 0, 1, 0 FROM DUAL UNION ALL
SELECT  9, 1, 0, 0 FROM DUAL UNION ALL
SELECT 10, 0, 1, 0 FROM DUAL UNION ALL
SELECT 11, 0, 0, 1 FROM DUAL UNION ALL
SELECT 12, 1, 0, 0 FROM DUAL UNION ALL
SELECT 13, 1, 0, 0 FROM DUAL UNION ALL
SELECT 14, 1, 0, 0 FROM DUAL UNION ALL
SELECT 15, 1, 0, 0 FROM DUAL UNION ALL
SELECT 16, 1, 0, 0 FROM DUAL UNION ALL
SELECT 17, 1, 0, 0 FROM DUAL UNION ALL
SELECT 18, 1, 0, 0 FROM DUAL UNION ALL
SELECT 19, 1, 0, 0 FROM DUAL UNION ALL
SELECT 20, 1, 0, 0 FROM DUAL

输出:

ID A B C ROW_AFTER_NEXT_MATCH NUM_MATCHES
1 1 0 0 0
2 1 0 0 0
3 0 1 0 0
4 1 0 0 0
5 0 1 0 1
6 0 0 1 12 2
7 1 0 0 13 2
8 0 1 0 1
9 1 0 0 1
10 0 1 0 1
11 0 0 1 2
12 1 0 0 2
13 1 0 0 1
14 1 0 0 1
15 1 0 0 1
16 1 0 0 18 5
17 1 0 0 19 5
18 1 0 0 20 5
19 1 0 0 21 5
20 1 0 0 5

db<>fiddle here