2016-10-14 32 views
0

我有3個表,products,productscategoriescategoriesMysql組與多列內連接

productscategories是一個多對多的表,只有其他兩個表的id號。

沒有GROUP BY看起來像這樣的結果:

id | Url     | Category 
------------------------------------- 
1 | http://example.com/12 | hat 
2 | http://example.com/12 | shoe 
3 | http://example.com/13 | hat 
4 | http://example.com/13 | jacket 
5 | http://example.com/14 | hat 
6 | http://example.com/14 | socks 

現在我想排除的每一行與同url如果它包含任何已選定的類別,在這種情況下jacketshoe

不需要的結果是這樣的:

id | Url     | Category 
------------------------------------- 
1 | http://example.com/12 | hat 
3 | http://example.com/13 | hat 
5 | http://example.com/14 | hat 

因爲url id爲13包括jacket我不想在那兒。 url與14相同,其中包括shoe

這是因爲我有多個類別和多個不知道對方的網址。

用SQL的上述:

SELECT * FROM products 
JOIN productscategories ON products.id = productscategories.product_id 
JOIN categories ON categories.id = productscategories.category_id 
WHERE categories.slug NOT IN (
    'shoe', 
    'jacket', 
) 
GROUP BY products.image_url 

的通緝的結果:

id | Url     | Category 
------------------------------------- 
5 | http://example.com/14 | hat 

我怎樣才能使一個SQL查詢,使URL意識到類的,像上面?

回答

1
SELECT * FROM products 
    JOIN productscategories ON products.id = productscategories.product_id 
    JOIN categories ON categories.id = productscategories.category_id 
GROUP BY products.image_url 
HAVING sum(categories.slug IN('shoe','jacket'))=0 

categories.slug IN('shoe','jacket') - 返回1,如果在組類別或0,如果不是。 sum() - 組中鞋子/夾克的退貨數量。 HAVING過濾器組與鞋/夾克在裏面。

+0

這是一個奇怪的尋找答案,但它在我的測試中很有用,它也很快閃爍(比其他答案快30-60倍)。沒有陷阱?謝謝! –

+1

@JensTörnell在MySQL上的工作正常。在其他RDBMS可能需要'sum(case when categories.slug IN('shoe','jacket')then 1 else 0 end)'' – Mike

1

建議1:WHERE NOT EXISTS

SELECT * FROM products 
JOIN productscategories ON products.id = productscategories.product_id 
JOIN categories ON categories.id = productscategories.category_id 
WHERE NOT EXISTS(
     SELECT 1 
     FROM products p2 
     JOIN productscategories pc2 ON p2.id = pc2.product_id 
     JOIN categories c2 ON c2.id = pc2.category_id 
     WHERE c2.slug IN ('shoe','jacket') 
     AND p2.url = products.url 
) 

建議2:OUTER JOIN

SELECT * FROM products 
JOIN productscategories ON products.id = productscategories.product_id 
JOIN categories ON categories.id = productscategories.category_id 
LEFT OUTER JOIN products p2 ON products.url = p2.url 
LEFT OUTER JOIN productscategories pc3 ON p2.id = pc2.product_id 
LEFT OUTER JOIN categories c2 ON c2.id = pc2.category_id AND c2.slug IN ('shoe','jacket') 
WHERE c2.id IS NULL 
+0

我只是想他們倆和他們的工作,但加載時間從1秒去喜歡一個半分鐘。 :(你的代碼中有'pc3',它應該是'pc2'. –

0

試試這個:

SELECT * FROM (
SELECT * FROM products 
JOIN productscategories ON products.id = productscategories.product_id 
JOIN categories ON categories.id = productscategories.category_id 
) AS A 
LEFT JOIN 
(
SELECT Url FROM products 
JOIN productscategories ON products.id = productscategories.product_id 
JOIN categories ON categories.id = productscategories.category_id 
WHERE Categories.slug IN ('jacket', 'shoe') 
GROUP BY url 
) B ON B.url = A.url 
WHERE B.url IS NULL