我有一个名为 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 AND 56(完全匹配)的条目,然后通过部分匹配对其余条目进行排序 - 仅标记为 category_id = 50 的条目,下一个标记为 56 的条目等。
谢谢,
您需要按条目汇总数据,然后应用订单条件:
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'
and '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