我不确定如何表达这个问题,所以让我举一个问题的例子:
假设有一个表将项目映射到类别。每个项目可以包含任意数量的类别,每个类别当然可以包含任意数量的项目。所以你有一个看起来像这样的表:
items_categories
id item_id category_id
问题是,我想选择具有特定类别ID的所有项目ID。例如,选择所有item_id的category_id为1和2:我想找到与1和2类别相关的所有项目。显然我不能使用AND语句,OR语句将返回所有item_id的任何一个类别,但不一定都是。
这是我的解决方案,也是我能想到的最好的事情:选择category_id等于1或2的所有item_ids;在PHP中迭代结果并跟踪与category_id关联的item_id的数量;然后取消设置结果中没有指定数量的类别的所有item_ids。这是我的代码片段:
// assume $results is an array of rows from the db
// query: SELECT * FROM items_categories WHERE category_id = 1 OR category_id = 2;
$out = array();
foreach ($results as $result)
{
if (isset($out[$result['item_id']]))
$out[$result['item_id']] ++;
else
$out[$result['item_id']] = 1;
}
foreach ($out as $key=>$value)
{
if ($value != 2)
unset($out($key));
}
return array_keys($out); // returns array of item_ids
显然,如果你有很多不同的类别,你选择和处理的方式比理论上需要的更多。有什么想法吗?
谢谢!
编辑:以下是表格的示例以及我想要的信息:
id item_id category_id
1 1 1
2 1 2
3 2 1
4 3 2
所以说我有兴趣获得类别1和2的所有项目。我如何从我的示例表中获取项目#1,因为我只想要类别#1 和#2?如果我选择类别1 或 2的所有内容(如上例所示),我必须在这种情况下选择整个表格并“手动”删除item_id的2和3,因为它们没有关联同时包括第1类和第2类。希望这有助于澄清一点。
最终编辑:我明白了,尽管我显然无法描述我正在尝试做什么,呵呵。这是我提出的查询,记录:
SELECT *
FROM
(
SELECT item_id, COUNT(*) as count
FROM items_categories
WHERE category_id IN (1, 2)
GROUP BY item_id
) table_count
WHERE count = 2;
在这种情况下,“(1,2)”可以替换为“( category_id1 , category_id2 ,...)”和“2”最后将替换为我正在搜索的类别数量。
因此,它找出了与每个项目的条件匹配的类别数量,并且因为我只想要所有类别匹配的项目,所以它只选择那些类别数量等于我正在寻找的类别数量的项目。这当然是假设没有重复的类别或类似的东西。
感谢您的回复!
答案 0 :(得分:1)
令您不安的是,您被迫进行线性搜索,当然需要花费O(n)时间,但如果您按照排序顺序从数据库中选择元素,那么您不能只使用在O(lg n)时间内进行二进制搜索?
我希望这有帮助,如果没有,那么也许我误解了你的问题,我希望你澄清一下。
答案 1 :(得分:0)
SELECT
foo
FROM
bar
WHERE
foo IN (1,2)
这就是你要找的东西吗?
答案 2 :(得分:0)
这是你应该让数据库去做而不是PHP。
SELECT item_id # We want a list of item ids
FROM cat_items # Gets the item ID list from the cat_items table
WHERE cat_id IN (1, 2, 7, 11) # List of categories you want to search in
GROUP BY item_id; # As the same item can appear in more than one category this line will eliminate duplicates
此查询确实假设cat_items中的数据是准确的,换句话说,类别和项目ID分别指向类别和项目表中的有效条目。如果您正在使用具有外键支持的数据库(用于MySQL,Postgres等的InnoDB引擎),则强制执行外键并不困难。
要以您想要的格式获取每个类别中的ID列表,这也很容易在SQL端完成。
SELECT *
FROM cat_items
WHERE cat_id IN (1, 2, 7, 11)
GROUP BY cat_id, item_id;
如果您只想计算每个类别中有多少项,您也可以在SQL中执行此操作
SELECT cat_id, COUNT(item_id) AS items
FROM cat_items
WHERE cat_id IN (1, 2, 7, 11)
GROUP BY cat_id;
如果您需要的数据不仅仅是ID,那么您可以加入需要数据的表。
SELECT items.*
FROM cat_items
JOIN items ON cat_items.item_id = items.id
WHERE cat_id IN (1, 2, 7, 11)
GROUP BY item_id;
答案 3 :(得分:0)
SELECT item_id FROM items_categories WHERE category_id = 1 AND item_id IN (SELECT item_id FROM items_categories WHERE category_id = 2)