0

我有一个复杂的导航,可以对内容库进行排序。导航对应类别,图库需要根据导航中选择的类别显示不同的内容组合。导航结构如下:

GROUP 1
category 1
category 2
category 3

GROUP 2
category 4
category 5
category 6

GROUP 3
category 7
category 8
category 9

我需要编写一个 MySQL 查询,将每个组内的所有项目视为 OR 语句。因此,选择类别 1 和类别 2,应返回同时标记为类别 1 和类别 2 的所有项目。

并且,每个组之间的项目需要被视为 AND 语句。因此,选择类别 1 和类别 4 只会返回同时包含在类别 1 和类别 4 中的项目。

我可以以简单的形式完成这两个查询,但是当我需要在每个组中包含多个具有多个类别的组时,我似乎无法完成它。

在英语中,最终查询需要能够执行以下操作:

"category 1" OR "category 2" OR "category 3" 
AND
"category 4" OR "category 5"
AND
"category 6" OR "category 7"

为此,我一直在为许多查询的许多版本而苦苦挣扎,目前我没有一个可行的答案。作为参考,如果值得的话,这是我目前拥有的:

SELECT ct.entry_id,
    ct.entry_date AS date,
    ct.title AS title,
    cp.cat_id AS category_id
FROM exp_channel_titles AS ct
LEFT JOIN exp_channel_data AS cd ON ct.entry_id = cd.entry_id
LEFT JOIN exp_category_posts AS cp ON ct.entry_id = cp.entry_id
WHERE ct.channel_id = '2'                        
AND ct.site_id = '1'

AND cp.cat_id IN (119)
AND cp.cat_id IN (121)

GROUP BY ct.entry_id 
ORDER BY ct.entry_date DESC

where 原因中的 cat_id 行似乎是需要整理的。我也尝试过使用 HAVING,这是我在广义上工作的,但我并不真正理解它,所以我尝试修改它以用于更具体的用途(如果它甚至是正确的使用方式)我' m 没有得到任何有用的结果。以下查询中的变量是根据检查的类别动态构建的:

AND ct.entry_id IN (SELECT entry_id
                FROM exp_category_posts 
                WHERE cat_id IN (".$category_ids.") 
                GROUP BY entry_id
                HAVING COUNT(DISTINCT cat_id) = " . 
                count($category_array) . ")

任何指导将不胜感激。

更新:感谢戈登的回答,我现在有一个有效的查询。虽然查询的某些部分是动态构建的(例如选择了哪些类别 ID),但这里是查询的静态版本以供参考:

SELECT ct.entry_id,
   ct.entry_date AS date,
   ct.title AS title,
   cp.cat_id AS category_id
FROM exp_channel_titles AS ct
LEFT JOIN exp_channel_data AS cd ON ct.entry_id = cd.entry_id
LEFT JOIN exp_category_posts AS cp ON ct.entry_id = cp.entry_id
WHERE ct.channel_id = '2'                        
AND ct.site_id = '1'
GROUP BY ct.entry_id 
HAVING MAX(CASE WHEN cp.cat_id IN (119,122) THEN 1 ELSE 0 END) = 1 AND
       MAX(CASE WHEN cp.cat_id IN (129,127) THEN 1 ELSE 0 END) = 1 AND
       MAX(CASE WHEN cp.cat_id IN (140) THEN 1 ELSE 0 END) = 1 
ORDER BY ct.entry_date DESC
4

1 回答 1

1

因此,您似乎有一个表 category_posts,每个 entry_id 有多行。您希望 entry_id 各行中的类别满足您的条件。

这需要一个有子句:

select cp.entry_id
from category_posts cp left outer join
     group1 g1
     on cp.cat_id = g1.cat_id left outer join
     group2 g2
     on cp.cat_id = g2.cat_id left outer join
     group3 g3
     on cp.cat_id = g3.cat_id
group by cp.entry_id
having max(case when g1.cat_id is not null then 1 else 0 end) = 1 and
       max(case when g2.cat_id is not null then 1 else 0 end) = 1 and
       max(case when g3.cat_id is not null then 1 else 0 end)

也就是说,每个组至少有一个代表类别。

于 2012-08-28T00:36:50.330 回答