![](/img/trans.png)
[英]Filter one category of a product, but bring all categories of the filtered products
[英]Need a MySQL JOIN to return all categories a product is in, per product, even if only one category is searched for
我定義了以下表格:
CREATE TABLE products (
product_id INTEGER(11) NOT NULL AUTO_INCREMENT,
name VARCHAR(255) NOT NULL,
section VARCHAR(255) DEFAULT NULL,
PRIMARY KEY (product_id)
) ENGINE=MyISAM;
CREATE TABLE categories (
category_id INTEGER(11) NOT NULL AUTO_INCREMENT,
name VARCHAR(255) NOT NULL,
PRIMARY KEY (category_id)
) ENGINE=MyISAM;
CREATE TABLE product_categories (
product_id INTEGER(11) NOT NULL,
category_id INTEGER(11) NOT NULL,
PRIMARY KEY (product_id, category_id)
) ENGINE=MyISAM;
實際上還有更多,這是優化更大,更復雜的查詢的一部分。 部分原因是將一些緩慢的子查詢移動到視圖中,這對視圖有很大幫助。
當我添加categories / product_categories表並且允許用戶按products.section或categories.category_id搜索時,查詢變得非常慢。 UI將這些作為搜索參數傳遞給我,並且我試圖獲得每個產品的行,其中包含其ID,名稱,部分以及與其關聯的以逗號分隔的類別名稱列表。 通過以下視圖和查詢,我能夠更快地完成:
CREATE OR REPLACE
ALGORITHM = MERGE
VIEW view_products_with_categories
AS
SELECT
p.product_id,
p.name,
p.section,
pc.name AS category
products p
LEFT JOIN product_categories pc on p.product_id = pc.product_id
LEFT JOIN categories c ON pc.category_id = c.category_id;
SELECT
product_id,
name,
section,
GROUP_CONCAT(DISTINCT category ORDER BY category) AS categories
FROM view_products_with_categories
GROUP BY product_id;
假設我們有以下行:
product_id name section category_id category
332913 Model Train Engine child-and-baby 1160 child-and-baby>baby-and-pre-schooltoys>playsets
332913 Model Train Engine child-and-baby 1308 toys>baby-and-preschool>playsets
332913 Model Train Engine child-and-baby 1312 toys>carstrains-and-planes>cars-and-vehicles
上面的簡單查詢給出了以下內容:
product_id name section categories
332913 Model Train Engine child-and-baby child-and-baby>baby-and-pre-schooltoys>playsets,toys>baby-and-preschool>playsets,toys>carstrains-and-planes>cars-and-vehicles
那沒關系,正如預期的那樣。 但是,我希望用戶能夠通過category_id進行搜索。 目前,我們的UI在類別名稱上做了一些自動完成的魔術,並為動態生成的SQL添加了一個過濾器,其中包含了category_id。 如果我在GROUP_CONCAT查詢中離開了category_id,它將是1160.假設他們想要搜索第二個(1308),所以我們修改查詢,如下所示:
SELECT
product_id,
name,
section,
GROUP_CONCAT(DISTINCT category ORDER BY category) AS categories
FROM view_products_with_categories
WHERE category_id = 1308
GROUP BY product_id;
現在我們得到以下內容:
product_id name section categories
332913 Model Train Engine child-and-baby toys>baby-and-preschool>playsets
再一次,正是你所期待的。 但是,客戶希望查看與產品相關的所有類別,這些類別包含他們正在搜索的一個或多個類別。 那么,讓我們制作一些簡化的樣本數據來向您展示我正在尋找的東西:
product_id name section category_id category
1 product_1 section_1 1 category_1
1 product_1 section_1 2 category_2
1 product_1 section_1 3 category_3
2 product_2 section_2 3 category_3
2 product_2 section_2 4 category_4
2 product_2 section_2 5 category_5
如果用戶搜索category_id = 3,我希望他們獲得以下內容:
product_id name section categories
1 product_1 section_1 category_1, category_2, category_3
2 product_2 section_2 category_3, category_4, category_5
但我目前只得到:
product_id name section categories
1 product_1 section_1 category_3
2 product_2 section_2 category_3
在沒有子查詢的情況下,我無法找到一種方法,其緩慢是我首先轉向視圖的原因。 我希望有一些令人眼花繚亂的明顯我錯過了,可能是因為睡眠不足,所以任何幫助都會受到贊賞。
更新 :我還應該提到產品可能不屬於任何類別,因此我的代碼中的LEFT JOIN。
以下查詢有效:(雖然我沒有使用該視圖)
select pc1.product_id, products.name, products.section,
group_concat(categories.name)
from products
inner join product_categories pc1
on (pc1.product_id = products.product_id and pc1.category_id = 3)
inner join product_categories pc2
on (pc2.product_id = products.product_id)
inner join categories
on (categories.category_id = pc2.category_id)
group by pc1.product_id, products.name, products.section
如果要使用該視圖,以下內容將起作用:
SELECT vpc.product_id,vpc.name,vpc.section,
GROUP_CONCAT(DISTINCT category ORDER BY category) AS categories
FROM view_products_with_categories vpc
inner join product_categories pc
on (pc.product_id = vpc.product_id and pc.category_id=3)
GROUP BY vpc.product_id, vpc.name, vpc.section;
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.