假设类别位于名为@Categories 的列中。为方便起见,我将假设它们是逗号分隔的,而不是空格分隔的(您可以在下面的代码中使用替换)。这简化了解释。
select
from files f
order by (find_in_list(reverse(substring_index(reverse(substring_index(@Categories, ',', 1))), ',' 1), f.categories) > 0) +
(find_in_list(reverse(substring_index(reverse(substring_index(@Categories, ',', 2)), ',' 1)), f.categories) > 0) +
(find_in_list(reverse(substring_index(reverse(substring_index(@Categories, ',', 3)), ',' 1)), f.categories) > 0) +
(find_in_list(reverse(substring_index(reverse(substring_index(@Categories, ', ', 4), ',' 1)), f.categories) > 0) +
(find_in_list(reverse(substring_index(reverse(substring_index(@Categories, ',', 5)), ',' 1)), f.categories) > 0) +
(find_in_list(reverse(substring_index(reverse(substring_index(@Categories, ',', 6)), ',' 1)), f.categories) > 0) desc
(注意:这是未经测试的。)
关键是表达式:
(find_in_list(reverse(substring_index(reverse(substring_index(@Categories, ',', <n>)), ',' 1)), f.categories) > 0) +
让我们从里到外解释一下:
该表达式substring_index(@Categories, ',', <n>)
返回类别字符串,直到第 n 个类别。
然后reverse
反转这个字符串,所以现在第 n 个是第一个。
nextsubstring_index
返回此字符串的第一个元素,即原始字符串的第 n 个元素。但是,它被颠倒了,所以下一个reverse
。最后,find_in_set()
在文件的类别中查找此内容。
整个order by
子句将这些值加在一起(布尔加起来就像 MySQL 中的整数一样)。所以,你得到了匹配的数量——这就是你想要对原始数据进行排序的方式。
综上所述,这是一个糟糕的数据结构。如果您以更规范的形式存储它,则解决方案会容易得多。