我想用一些ID数组过滤我的SQL查询。

所以我有ID例如:2,3,4和activity_meta.value 1,2,5;
我想在activity_meta.value中找到ID为ID的每个活动

SELECT DISTINCT a.*, u.user_email, u.user_nicename, u.user_login, u.display_name
FROM wp_bp_activity a
LEFT JOIN wp_users u
ON a.user_id = u.ID
INNER JOIN wp_bp_activity_meta
ON (a.id = wp_bp_activity_meta.activity_id)
WHERE a.is_spam = 0
AND a.hide_sitewide = 0
AND a.type != 'activity_comment'
AND  (wp_bp_activity_meta.meta_key = 'activity_tagz' )
DESC LIMIT 0, 20


我要添加AND (1,2,3 IN wp_bp_activity_meta.meta_value)
我只是不知道如何处理序列化数组。

最佳答案

activity_meta.value的值未标准化。创建第二张表是一个更好的选择,您可以在其中将meta标签分配给元素。

因此,它看起来像:

wp_bp_activity_id | meta
1              | 1
1              | 2
1              | 3


让我们校准该表“ meta_relation”。然后,您可以简单地使用子选择,如下所示:

... WHERE wp_bp_activity.id in (SELECT wp_bp_activity_id FROM meta_relation WHERE meta in (1,2,5))


或者您可以通过另一个联接来实现此目标,例如

... INNER JOIN meta_relation ON wp_bp_activitiy.id = meta_relation.wp_bp_activity_id


(将返回3行,然后返回3个匹配的标签)

... WHERE meta in (1,2,5)
... GROUP BY wp_bp_activity.id


(将删除所有重复的结果和不需要的标签)



对于当前情况,您可以使用解决方法。但是,这需要以编程方式构建查询:

对于每个“标记”,您需要查找(即1,2,5)您需要添加另一个or条件。


为了确保您不匹配2中的125,可以用,对其进行环绕。
为了确保您不会错过FIRST或LAST项(没有前导/尾随,的情况,您首先需要将列与另外2个,连接起来:


然后查询包含以下附加条件。

SELECT
   ....
WHERE
   ...
AND
(
   CONCAT(CONCAT(",", activity_meta.value ), ",") LIKE "%,1,%" OR
   CONCAT(CONCAT(",", activity_meta.value ), ",") LIKE "%,2,%" OR
   CONCAT(CONCAT(",", activity_meta.value ), ",") LIKE "%,5,%"
)


如果要显示所有3个标记,请使用AND而不是OR

在您的示例中,这将匹配:

,2,3,4, against ,1,
,2,3,4, against ,2, //match
,2,3,4, against ,5,


顺序和/或差距与这种方法无关紧要。

(根据使用的是10个用户的网站还是一个百万级客户的门户网站,您可以使用这两种方法。首选解决方案是对表进行规范化。)

09-25 18:24
查看更多