由于关系数据库的性质,我认为这样的查询会很容易,但它似乎让我很合适。我也四处搜寻,但没有发现任何真正有帮助的东西。情况如下:
假设我对产品和产品标签有一个简单的关系。这是一对多的关系,所以我们可以有以下内容:
productid | tag
========================
1 | Car
1 | Black
1 | Ford
2 | Car
2 | Red
2 | Ford
3 | Car
3 | Black
3 | Lexus
4 | Motorcycle
4 | Black
5 | Skateboard
5 | Black
6 | Skateboard
6 | Green
查询 all的最有效(Ford OR Black OR Skateboard) AND NOT (Motorcycles OR Green)
方法是什么?我需要做的另一个查询是 all (Car) or (Skateboard) or (Green AND Motorcycle) or (Red AND Motorcycle)
。
products 表中有大约 150k 条记录,tags 表中有 600k 条记录,因此查询需要尽可能高效。这是我一直在搞乱的一个查询(示例#1),但它似乎需要大约 4 秒左右。任何帮助将非常感激。
SELECT p.productid
FROM products p
JOIN producttags tag1 USING (productid)
WHERE p.active = 1
AND tag1.tag IN ( 'Ford', 'Black', 'Skatebaord' )
AND p.productid NOT IN (SELECT productid
FROM producttags
WHERE tag IN ( 'Motorcycle', 'Green' ));
更新
到目前为止我发现的最快的查询是这样的。它需要 100-200 毫秒,但它看起来非常不灵活和丑陋。基本上我会抓住所有匹配Ford
,Black
或的产品Skateboard
。他们我将这些匹配产品的所有标签连接到一个冒号分隔的字符串中,并删除所有与:Green:
AND匹配的产品:Motorcycle:
。有什么想法吗?
SELECT p.productid,
Concat(':', Group_concat(alltags.tag SEPARATOR ':'), ':') AS taglist
FROM products p
JOIN producttags tag1 USING (productid)
JOIN producttags alltags USING (productid)
WHERE p.active = 1
AND tag1.tag IN ( 'Ford', 'Black', 'Skateboard' )
GROUP BY tag1.productid
HAVING ( taglist NOT LIKE '%:Motorcycle:%'
AND taglist NOT LIKE '%:Green:%' );