SQL:将一组单词与另一组匹配,并按匹配的count和prefix-ness排序

时间:2015-07-30 19:56:41

标签: sql postgresql string-matching unnest

我需要将用户输入与字符串列匹配。两者都包含空格分隔的单词。

订购标准是:

  1. 从头开始匹配的单词数(前缀匹配) desc
  2. 匹配 desc
  3. 的字数
  4. 匹配的单词与输入短语的顺序相同的列
  5. 所以给出以下样本数据

    "one sample"
    "un moment"
    "no match"
    "sample uno"
    "uno sample"
    "sample oun"
    

    和示例输入"sa un foo",输出应为:

    1. "sample uno" - 2个前缀匹配
    2. "uno sample" - 相同但单词的顺序不同
    3. "sample oun" - 1个前缀匹配+ 2个匹配的词
    4. "un moment", "one sample" - 1个前缀匹配
    5. 问题是:我可以在单个SQL查询(postgresql)中实现这个吗? 我对SQL很缺乏经验,所以我很感激任何帮助。谢谢!

      我添加了一个简单的SQL FIDDLE

1 个答案:

答案 0 :(得分:1)

  • 首先对每行进行asign和id
  • space
  • 拆分每个数据
  • space
  • 拆分输入
  • 交叉连接两个表并检查输入是否出现在数据上。
  • 最后联接回原始表并计算前缀和包含的数量。

如果一个输入字显示为前缀而第二个字显示为包含相同字,则我认为可能需要特殊注意

  

数据:FORMAT
  输入:FO AT

SQL FIDDLE DEMO

WITH data as  (
    SELECT 
         row_number() OVER (ORDER BY field) AS id,
         field
    FROM 
      dtable
),
data_split as (
    SELECT
        id,
        unnest(string_to_array(field, ' ')) AS elem
    FROM data
),
input_split as (
    SELECT
        unnest(string_to_array(field, ' ')) AS elem
    FROM input
),
match as (
    SELECT *, strpos(d.elem, i.elem) as match_pos
    FROM   input_split i, data_split d
)
select 
    match.id, 
    data.field,
    SUM( CASE WHEN match_pos = 1 THEN 1 ELSE 0 END ) prefix,
    SUM( CASE WHEN match_pos > 1 THEN 1 ELSE 0 END ) contain
from  
    match inner join
    data on match.id = data.id
group by match.id, data.field
order by 3 desc, 4 desc

enter image description here