2013-06-18 136 views
3

我有一个有两列(entry_id和CATEGORY_ID)精确匹配,那么部分匹配

entry_id | category_id 
52 | 44 
55 | 47 
58 | 50 
55 | 55 
58 | 52 
53 | 51 
58 | 56 
61 | 56 

如何选择标记有CATEGORY_ID 50和56(精确匹配)中的所有条目的表中调用的帖子第一然后为了通过部分匹配其余的 - 项只有CATEGORY_ID = 50,标记56个

感谢下一条目,标记

回答

4

你需要通过汇总录入数据,然后套用阶条件:

select entry_id 
from posts 
group by entry_id 
order by max(category_id = 50) + max(category_id = 56) desc 

表达max(category_id = 50)返回1如果50类是在混合(对于条目)和0否则。通过一起添加这两个表达式,您可以获得类别匹配的数量。

如果你关心的单场比赛的顺序(对这个问题的建议),然后执行:

select entry_id 
from posts 
group by entry_id 
order by max(category_id = 50) + max(category_id = 56) desc, 
     max(category_id = 50) desc, 
     max(category_id = 56) desc 

编辑:

如果您存储可用类别以逗号分隔的列表,那么你可以拥有最好的世界。您可以通过匹配的类别数量(第一个)进行排序。然后,您可以使用该列表来优先分类。而且,您可以确保具有相同类别的所有实体一起出现。它只需要字符串操作。

表达:

count(distinct (case when find_in_set(category_id, @categories) > 0 then category_id end)) 

将计数的类别是在列表中的号码(实体)。

表达:

group_concat((case when find_in_set(category_id, @categories) > 0 
        then find_in_set(category_id, @categories) 
       end) 

将创建其中元素表示该串中的位置的字符串。因此,如果您通过'a,b,c;且实体匹配'b''c',则字符串将是'2,3'。如果它有全部三个,那么它将是'1,2,3'。这提供了您需要优先化的内容。

最后,在结尾处增加entity_id可使排序稳定:

order by count(distinct (case when find_in_set(category_id, @categories) > 0 then category_id end)) desc, 
     group_concat((case when find_in_set(category_id, @categories) > 0 
          then find_in_set(category_id, @categories) 
         end) 
         order by find_in_set(category_id, @categories)), 
     entry_id 
+0

谢谢你,只是一个简单的问题是:如果我不知道类别出来的确切顺序,我会怎么修改这个?基本上,数据是以随机顺序输出,具体取决于页面? – Daniel

+0

@Daniel。 。 。在entry_id上的'order by'子句中添加最后的排序。这将使排序稳定。 –

+0

这将如何工作,但如果category_id动态出现而不是按照这个顺序?例如,在一个实例中,它可能如上所述是50和56,但在另一个实例中,输出可能是44 | 50 | 52 | 56。基本上entry_id被分配到多个和多个类别,所以如果我通过PHP获取值,我将如何动态地将这些值放入查询中? – Daniel