完全匹配,然后部分匹配

时间:2013-06-18 16:45:07

标签: mysql sql

我有一个名为posts的表,它有两列(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的其他条目等。

谢谢,

1 个答案:

答案 0 :(得分:4)

您需要按条目汇总数据,然后应用订单条件:

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

如果类别50在混合中(对于条目),则表达式max(category_id = 50)返回1,否则返回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