如何根据OR查询中的匹配项对行进行评分?

时间:2019-07-03 15:11:05

标签: postgresql sql-order-by postgresql-11

我正在尝试根据使用OR子句指定的一组可变条件对行进行评分,并希望返回具有大量直接匹配项的行。

这是针对postgres 9.1 (已编辑) 11.1 的,而我的最初尝试(基于我试图重新引用的堆栈溢出文章)大致如下:< / p>

SELECT                                                                          
  T.id,                                                                         
  (                                                                             
    SELECT                                                                      
    count(*)                                                                    
    FROM (                                                                      
      VALUES                                                                    
        (T.criteria1),                                                               
        (T.criteria2),                                                              
        (T.criteria3),                                                      
        (T.criteria4)                                                              
    ) AS VALS(col)                                                              
    WHERE VALS.col IS NOT NULL                                                  
  ) AS score                                                                    
  FROM my_table AS T                                                     
  WHERE T.other_criteria = 'somevalue'                                                    
    AND (                                                                       
      T.criteria1='foo'                                                              
      OR T.criteria2='bar'                                                          
      OR T.criteria3 = 'baz                                                          
      OR T.criteria4 = 'stackoverflow'                                                        
    )                                                                           
    ORDER BY score DESC                                                         
    LIMIT 1;        

起初我以为它可以正常工作,但是后来我意识到它的实际作用就是将与OR匹配的行中的非空值数量加起来。与其让score成为非空列的计数,我不希望它成为与where条件匹配的列的计数。

例如,如果我有一个行匹配我的OR条件中的2个,我希望它返回2分,如果它匹配3个,则返回3分等等。

我尝试执行以下操作无济于事。

SELECT 
  T.id
 SUM(                                                                          
    (case when T.criteria1 = 'foo' then 1 else 0 end)  
    ...                              
  ) 
...

任何想法都将不胜感激。

1 个答案:

答案 0 :(得分:1)

您可以简单地

ORDER BY (T.criteria1 IS NOT DISTINCT FROM 'foo')::integer
       + (T.criteria2 IS NOT DISTINCT FROM 'bar')::integer
       + (T.criteria3 IS NOT DISTINCT FROM 'baz')::integer
       + (T.criteria4 IS NOT DISTINCT FROM 'stackoverflow')::integer DESC