2017-04-19 59 views
-3

数据给sql中查找模式并计算有多少次出现

22 
22 
22 
22 
22 
36 
54 
40 
22 
22 
22 
22 
36 
22 
22 
54 
22 
22 

这是在表中的列。使用SQL查询,我们需要找出图案如 22 36 54 40是第一图案然后22图36是第二和22 54是第三图案。

+1

什么是你的一个 “模式” 的定义开始?表格中是否有另一列将定义序列? – Squirrel

+1

那是什么? Microsoft SQL Server或PostgreSQL?这是两个非常不同的DBMS。 –

+1

另外:什么定义这些行的排序顺序?在关系数据库中的行不“排序”,所以如果你需要行的特定顺序,你需要一个列进行排序的。 –

回答

1

您应该使用LEAD来获取下一行的值,看看它是否是22,并使用它来摆脱列中所有额外的22。东西这种效果:

declare @t table (id int identity(1,1) not null, n int) 
insert into @t 
select 22 union all 
select 22 union all 
select 22 union all 
select 22 union all 
select 22 union all 
select 36 union all 
select 54 union all 
select 40 union all 
select 22 union all 
select 22 union all 
select 22 union all 
select 22 union all 
select 36 union all 
select 22 union all 
select 22 union all 
select 54 union all 
select 22 union all 
select 22 

select id,n from (select id,n ,lead(n) over (order by id) 
as lead_val from @t) t where n<>22 or lead_val<>22 

此输出:

5 22 
6 36 
7 54 
8 40 
12 22 
13 36 
15 22 
16 54 
+0

这是因为两个原因一个坏的解决方案:**(1)**的模式不能在这个结果的格式可见。例如。没有任何信息表明id 12和id 13属于相同的模式。 **(2)**这个结果可以通过一个简单得多的代码来实现,选择我,val from(select i,val ,lead(val)over(order by i)as lead_val from mytable )t 其中val <> 22 或lead_val <> 22' –

+0

是的,这是一个简单的查询 - 我我的答案更新确认。 –

0

的PostgreSQL

假设:

  • 有确定所述元素的顺序的列
  • 种所有模式与22

select  array_to_string(array_agg(val order by i),',') as pattern 
      ,min (i)          as from_i 
      ,max (i)          as to_i 
      ,count(*)          as pattern_length   

from  (select i,val 
        ,count(case when val = 22 then 1 end) over 
        (
         order by i 
         rows unbounded preceding 
        ) as pattern_id 

      from mytable 
      ) t 

group by pattern_id 

having  count(*)>1 
; 

+-------------+--------+------+----------------+ 
| pattern | from_i | to_i | pattern_length | 
+-------------+--------+------+----------------+ 
| 22,36,54,40 |  5 | 8 |    4 | 
| 22,36  |  12 | 13 |    2 | 
| 22,54  |  15 | 16 |    2 | 
+-------------+--------+------+----------------+