在Firebird中使用SIMILAR TO如何找到几个单词是否匹配

时间:2011-08-12 23:28:12

标签: sql firebird

我正在使用Firebird 2.5,我必须按任意顺序查找包含多个单词的行:

找到'blue''house':

'树林里的蓝屋'=真实 '有蓝色窗户的房子'=真实 “海边的房子”=假 '蓝色汽车'=真实

使用管道“|”给我OR,我需要AND,但不管是2个单词,还是更多 我正在尝试使用SIMILAR TO,但似乎Firebird中的RegExpr太有限了。

使用几个LIKE x AND LIKE y,不是你走的路,因为我不知道要找多少个字。

3 个答案:

答案 0 :(得分:1)

您只能使用Firebird方法解决您的任务。假设您有一个名为TEST的表,其中包含唯一字段S.

CREATE TABLE TEST (S VARCHAR(256))

其中包含短语:

  'a blue house in the woods' 
  'a house with blue windows' 
  'a house by the beach' 
  'the blue car'
  ...

您需要创建一个辅助可选程序SPLIT_WORDS:

CREATE OR ALTER PROCEDURE split_words (S VARCHAR(256))
  RETURNS(
    K VARCHAR(256),
    W VARCHAR(256))
AS
  DECLARE VARIABLE B INTEGER = 1;
  DECLARE VARIABLE E INTEGER = 1;
  DECLARE VARIABLE C CHAR(1);
BEGIN
  K = :S;
  WHILE (:E <= CHAR_LENGTH(:S)) DO
  BEGIN
    C = UPPER(SUBSTRING(:S FROM :E FOR 1));
    IF (:C < 'A' OR :C > 'Z') THEN
    BEGIN
      W = SUBSTRING(:S FROM :B FOR (:E - :B));

      IF (:W > '') THEN
        SUSPEND;

      WHILE (:E <= CHAR_LENGTH(:S)) DO
      BEGIN
        C = UPPER(SUBSTRING(:S FROM :E FOR 1));
        IF (:C >= 'A' AND :C <= 'Z') THEN
          LEAVE;
        E = :E + 1;
      END

      B = :E;
    END
    E = :E + 1;
  END

  W = SUBSTRING(:S FROM :B FOR (:E - :B));
  IF (:W > '') THEN
    SUSPEND;
END

用于将给定字符串拆分为单词的过程。任何非字母字符都被视为分隔符。

使用此程序可以编写一个查询,它将以任何顺序返回所有带有'HOUSE'和'BLUE'字样的字符串。

SELECT
  tt.s
FROM
  test tt JOIN
    (SELECT
        t.s, COUNT(s2.w) c
      FROM
        test t LEFT JOIN split_words(t.s) s ON 1=1
          LEFT JOIN split_words('blue house') s2 ON s.w=s2.w
      WHERE
        s2.w IS NOT NULL
      GROUP BY
        1
     ) ttt ON ttt.s = tt.s
WHERE
  ttt.c = (SELECT COUNT(*) FROM split_words('blue house'))

答案 1 :(得分:0)

据我所知,火鸟没有内置任何东西可以帮助你。

您真正需要的是全文搜索。虽然firebird没有直接支持,但这里有一些有用的建议:http://www.firebirdfaq.org/faq328/

祝你好运,对不起,我没有更直接的答案。

答案 2 :(得分:0)

您可以在参考手册中查看SIMILAR TO,但我认为您需要的更像是Sphinx