在m:m关系中找到字符串的第一个匹配项

时间:2019-01-16 19:35:58

标签: sql postgresql

在PostgreSQL中,表ab是m:m关系—如何找到所有出现的字符串:

  • 同时出现在a.stringb.string列中
  • 根据b.string的顺序,AND在a.string中发生,然后在ab.id中发生

例如,"hello"同时出现在a.stringb.string列中,并且按照b.string的顺序在ab.id中首先出现,因此"hello"结果将返回。

类似的东西:

select *
from table ab
left join table a on (a.id = ab.a_id)
left join table b on (b.id = ab.b_id)
-- pseudo: 
  -- where b.string "hello" occurs first
  -- and a.string "hello" also exists
order by ab.id


ab.id | ab.a_id | ab.b_id | a.string | b.string 
-----------------------------------------------------
  1      63        59       'good bye'   > 'hello' -- appears first here
  2      75        67       > 'hello'    'sounds good'
  3      77        78       'have fun'   'awesome'

编辑:

基本上,该想法是用户应始终首先看到以a.string列的形式出现的字符串,然后是b.string。如果b.string实例首先出现,我们应该返回它。

我需要说明两种情况,其中满足上述条件。

1) b.string符合出现在a.string之前的条件,但这不是a.string的“ hello”的第一个实例-即,在第1行a.stringb.string是“ hello”,但随后第2行满足了b.string的“ hello”出现在a.string之前的条件:

ab.id | ab.a_id | ab.b_id | a.string | b.string 
-----------------------------------------------------
  1      63        59       'hello'      > 'hello' -- meets condition
  2      75        67       > 'hello'    'sounds good'
  3      77        78       'have fun'   'awesome'

2) a.stringb.string为NULL时出现在其他位置,然后b.string后面的任何其他行条件出现在a.string之前应该为假

ab.id | ab.a_id | ab.b_id | a.string | b.string 
-----------------------------------------------------
  1      63        59       'hello'      NULL
  2      75        67       'good bye'   'hello'
  3      77        78       'hello'      'awesome'

1 个答案:

答案 0 :(得分:1)

您有两个条件。存在和不存在浮现在脑海:

select ab.*
from ab
where not exists (select 1
                  from ab ab2
                  where ab2.astring = ab.bstring and
                        ab2.id < ab.id
                 ) and  -- no earlier "a"s
      exists (select 1
              from ab ab2
              where ab2.astring = ab.bstring 
             )          -- another "a"