从MySQL表中选择,按匹配的类别数排序

问题描述 投票:0回答:2

我有一张桌子,像这样:

id:int | name:String | categories:String

示例行:

1 | "Lorem1" | "A, B, C" 
2 | "Lorem2" | "A, B" 
3 | "Lorem3" | "A, C" 
4 | "Lorem4" | "B" 

我还有一个表格,您可以在其中查看您感兴趣的类别。这应该是选择顺序的指南。

首先,您将获得具有所有选定类别的行,然后您将获得具有更少匹配的行。 (如果该行没有任何类别,则不会显示)

如果有人例如检查:

  • A和B,它们应按此顺序取回行:Lorem1,Lorem2,Lorem3,Lorem 4
  • A和C,他们应按此顺序取回行:Lorem1,Lorem3,Lorem2

这就是我想要做的。我是编程的新手,这个问题出现了。

我也知道,也许我应该为类别和对象之间的连接建立一个新表。

php mysql sql
2个回答
0
投票

您可以使用find_in_set()检查逗号分隔列表中的字符串。但你必须首先replace()空间。对用户选择的每个类别执行此操作。然后检查find_in_set()的结果是否大于0,因为0表示它没有找到任何内容,否则它返回列表中的位置,该位置大于0.添加这些比较的结果。由于在数字上下文中为true的布尔运算为1,否则为0,则可以按该总和降序排序。即一行具有的匹配越多,它在结果中的排序就越早。

类别'A''C'的示例:

SELECT *
       FROM elbat
       ORDER BY (find_in_set('A', replace(categories, ' ', '')) > 0)
                +
                (find_in_set('C', replace(categories, ' ', '')) > 0)
                DESC;

您也可以使用它来排除没有任何匹配的行。总和将为0。

SELECT *
       FROM elbat
       WHERE (find_in_set('A', replace(categories, ' ', '')) > 0)
             +
             (find_in_set('C', replace(categories, ' ', '')) > 0)
             > 0
       ORDER BY (find_in_set('A', replace(categories, ' ', '')) > 0)
                +
                (find_in_set('C', replace(categories, ' ', '')) > 0)
                DESC;

但逗号分隔的列表很痛苦。您应该考虑修改架构并使用另一个表将项目链接到类别。


0
投票

您应该在用户表中定义ManyToManyfield,而不是将类别存储为字符串。因此,用户可以是一个或多个类别的一部分,反之亦然。类别表可以使用各自的ID存储不同的类别。

© www.soinside.com 2019 - 2024. All rights reserved.