最近需要做一个特征库,库每个表中存有若干条有顺序的特征数据,想利用数据库实现特征匹配,具体描述为:
假设存在特征表a:
id   Specific
1    aaaa
2    bbbb
3    cccc假设数据表为b:
id  Specific
1    dddd
2    eeee
3    aaaa
4    bbbb
5    cccc  假设数据表为c:
id  Specific
1    aaaa
2    cccc
3    dddd
4    bbbb
5    eeee假设数据表为d:
id  Specific
1    aaaa
2    bbbb
3    dddd
4    cccc
5    eeee假设数据表为e:
id  Specific
1    aaaa
2    dddd
3    bbbb
4    cccc
5    eeee
则认为c和d与a不匹配,b与a匹配,在数据库如何实现这样的匹配,非常感谢   

解决方案 »

  1.   

    select * from b minus (select * from b minus select * from a);剩下的结果中,如果id连续则匹配, 不连续则不匹配。
      

  2.   

    id和排序后的值相减,如果剩下的记录里结果为全0,那么就是连续的,否则不连续。剩下的记录数总和如果为3,那么则连续且连续三条特征,否则为不满足条件。下面示例。SQL> WITH t AS (SELECT 1 ID FROM dual UNION ALL SELECT 2 from dual UNION ALL SELECT 4 from dual)
      2  SELECT ID, row_number() OVER(ORDER BY 1), ID -(row_number() OVER(ORDER BY 1)) div, COUNT(ID) OVER(order BY 1) COUNT FROM t;
     
            ID ROW_NUMBER()OVER(ORDERBY1)        DIV      COUNT
    ---------- -------------------------- ---------- ----------
             1                          1          0          3
             2                          2          0          3
             4                          3          1          3
     
    SQL> 
    SQL> WITH t AS (SELECT 1 ID FROM dual UNION ALL SELECT 2 from dual UNION ALL SELECT 3 from dual)
      2  SELECT ID, row_number() OVER(ORDER BY 1), ID -(row_number() OVER(ORDER BY 1)) div, COUNT(ID) OVER(order BY 1) COUNT FROM t;
     
            ID ROW_NUMBER()OVER(ORDERBY1)        DIV      COUNT
    ---------- -------------------------- ---------- ----------
             1                          1          0          3
             2                          2          0          3
             3                          3          0          3
     
    SQL> 
      

  3.   

    表t是select * from b minus (select * from b minus select * from a);的结果。如果特征向量有3条,而表t的数据不等于3,那么显然不匹配。
    如果表t数据等于3,那么再做3楼的操作并检查DIV的值是否为全0,如是则匹配,否则不匹配。
      

  4.   

    还是出现了问题,在例表f
    id  Specific
    1    aaaa
    2    dddd
    3    bbbb
    4    cccc
    5    aaaa
    6    bbbb
    7    cccc
    8    eeee
    中使用3楼操作的话id和排序值相减的办法就不好使了,而且count的值也会大于3
      

  5.   

    如果特征表数据不多,可以把例表先变成这种结构,然后判断是否表中存在这样一条记录, 
    aa             bb   cc            dd            eeSQL> WITH t AS (SELECT 1 ID, 'aa' sepc FROM dual UNION ALL
      2  SELECT 2, 'bb'  FROM dual UNION ALL
      3  SELECT 3, 'cc'  FROM dual UNION ALL
      4  SELECT 4, 'dd'  FROM dual UNION ALL
      5  SELECT 5, 'ee'  FROM dual)
      6  SELECT LAG(sepc, 1, '00') OVER(order BY ID) previous_value, sepc, LEAD(sepc, 1, '00') OVER(ORDER BY  ID) behind_value1,
      7  LEAD(sepc, 2, '00') OVER(ORDER BY  ID) behind_value2,LEAD(sepc, 3, '00') OVER(ORDER BY  ID) behind_value3 FROM t;
     
    PREVIOUS_VALUE SEPC BEHIND_VALUE1 BEHIND_VALUE2 BEHIND_VALUE3
    -------------- ---- ------------- ------------- -------------
    00             aa   bb            cc            dd
    aa             bb   cc            dd            ee
    bb             cc   dd            ee            00
    cc             dd   ee            00            00
    dd             ee   00            00            00
     
    SQL> 
      

  6.   

    特征表的数据量不定,但是一般要有二三十条吧,而且是自动生成的,8楼的方法用起来有点困难。有没有可能利用以下思路解决呢:
    1、利用select a.id,a.Specific from a,f where a.Specific=f.Specific;选出所有在f中出现的a的数据。
    2、利用id号的连续性来判断是否匹配,例如,如果从id号1连续到3的数据则认为匹配。
      

  7.   

    id号连续以外,还要保证spec列也是一一对应的,如果能做到这点,#9是可以的。
      

  8.   

    否则有可能出现这种情况也会被选出来。
    特征表:
    1 'aa'; 2 'bb'; 3 'cc'例表:
    1 'aa'; 2 'cc'; 3 'bb' 
      

  9.   

    id与spec列的一一对应可以做到,现在就是在id连续性的判断上有问题,例如我要从1到15的,但是从2到10的以及从3到6的也都取出来了
      

  10.   

    12楼的问题mysql版的大神WWWWA给解决了,附代码insert into table select * from a,b where a.Specific=b.Specific;
    set @a=0;
    set @b=0;
    select id-1 @a from table limit 1;
    select PM,MIN(id) as mi,MAX(id) as mx from(
    select * from @b:=if(@a+1=id,@b,@b+1) as PM @a=id from table) 
    Group by PM having count(*)>=select count(*) from a;