由于关系数据库的性质,我认为这样的查询会很容易,但它似乎让我很合适。我也四处搜寻,但没有发现任何真正有帮助的东西。情况如下:
假设我对产品和产品标签有一个简单的关系。这是一对多的关系,所以我们可以有以下内容:
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:%' );