我有一个复杂的导航,可以对内容库进行排序。导航对应于类别,图库需要根据导航中选择的类别显示不同的内容组合。导航的结构如下:
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
原因中的cat_id行似乎需要整理出来。我也试过使用HAVING,我从广义上开始工作,但我并不是真的理解它,所以当我尝试修改它以获得更具体的用途时(如果它甚至是正确使用的话)我'没有得到任何有用的结果。以下查询中的变量是根据检查的类别动态构建的:
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
答案 0 :(得分:1)
所以,你似乎有一个table_posts,每个entry_id有多行。您希望entry_id的各行上的类别符合您的条件。
这需要一个having子句:
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)
也就是说,每组中至少有一个代表性类别。