SQLite 多对多加入和分组
SQLite many to many join and group
对于多对多关系 table,这是一个非常正常的设置。
product
列表和 category
列表。
- 每个
product
属于 (0,n)
category
。
- 每个
category
包含 (0,n)
product
。
表格
CREATE TABLE product (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL);
CREATE TABLE category (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL);
CREATE TABLE product_category (
product_id INTEGER NOT NULL,
category_id INTEGER NOT NULL);
产品table
| id | name |
=============
| 1 | p1 |
| 2 | p2 |
| 3 | p3 |
类别table
| id | name |
=============
| 1 | c1 |
| 2 | c2 |
| 3 | c3 |
PRODUCT_CATEGORY table
| product_id | category_id |
============================
| 1 | 1 |
| 1 | 2 |
| 1 | 3 |
| 2 | 1 |
| 2 | 2 |
| 3 | 1 |
问题
我想知道如何通过 category_id
查询 product
并列出 product
及其所在的所有 category_id
。
比如我想查询在category = 1中有货的products列表,结果必须包含一个categories_id
其中必须列出 product
所属的所有类别。
预期输出
| product_id | product_name | categories_id |
=============================================
| 1 | p1 | 1,2,3 |
| 2 | p2 | 1,2 |
| 3 | p3 | 1 |
尝试次数
我知道这可以通过子查询来完成,但我想知道这是否可以通过JOIN
语句来实现?
我尝试了以下查询,但结果并不符合我的要求。
JOIN QUERY 语句
SELECT
P.id AS product_id,
P.name AS product_name,
GROUP_CONCAT(PC.category_id, ',') AS categories_id
FROM product AS P
LEFT JOIN product_category AS PC
ON P.id = PC.product_id
WHERE PC.category_id = 1
GROUP BY P.id;
输出(不符合预期)
| product_id | product_name | categories_id |
=============================================
| 1 | p1 | 1 |
| 2 | p2 | 1 |
| 3 | p3 | 1 |
任何人都可以就如何实现这一点提出建议吗?
SELECT
p.id,
p.name,
GROUP_CONCAT(pc2.category_id, ',')
FROM product_category pc1
JOIN product_category pc2
JOIN product p
WHERE pc1.category_id = 1
AND pc1.product_id = pc2.product_id
AND p.id = pc1.product_id
GROUP BY pc1.product_id;
执行的是SqlFiddle,查询是
SELECT P.id AS product_id, P.name AS product_name,
GROUP_CONCAT(PC2.category_id) AS categories_id
FROM
product AS P LEFT JOIN product_category AS PC ON
P.id = PC.product_id LEFT JOIN product_category AS PC2 ON
P.id = PC2.product_id
WHERE PC.category_id = 1
GROUP BY P.id;
对于多对多关系 table,这是一个非常正常的设置。
product
列表和category
列表。- 每个
product
属于(0,n)
category
。 - 每个
category
包含(0,n)
product
。
表格
CREATE TABLE product (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL);
CREATE TABLE category (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL);
CREATE TABLE product_category (
product_id INTEGER NOT NULL,
category_id INTEGER NOT NULL);
产品table
| id | name |
=============
| 1 | p1 |
| 2 | p2 |
| 3 | p3 |
类别table
| id | name |
=============
| 1 | c1 |
| 2 | c2 |
| 3 | c3 |
PRODUCT_CATEGORY table
| product_id | category_id |
============================
| 1 | 1 |
| 1 | 2 |
| 1 | 3 |
| 2 | 1 |
| 2 | 2 |
| 3 | 1 |
问题
我想知道如何通过 category_id
查询 product
并列出 product
及其所在的所有 category_id
。
比如我想查询在category = 1中有货的products列表,结果必须包含一个categories_id
其中必须列出 product
所属的所有类别。
预期输出
| product_id | product_name | categories_id |
=============================================
| 1 | p1 | 1,2,3 |
| 2 | p2 | 1,2 |
| 3 | p3 | 1 |
尝试次数
我知道这可以通过子查询来完成,但我想知道这是否可以通过JOIN
语句来实现?
我尝试了以下查询,但结果并不符合我的要求。
JOIN QUERY 语句
SELECT
P.id AS product_id,
P.name AS product_name,
GROUP_CONCAT(PC.category_id, ',') AS categories_id
FROM product AS P
LEFT JOIN product_category AS PC
ON P.id = PC.product_id
WHERE PC.category_id = 1
GROUP BY P.id;
输出(不符合预期)
| product_id | product_name | categories_id |
=============================================
| 1 | p1 | 1 |
| 2 | p2 | 1 |
| 3 | p3 | 1 |
任何人都可以就如何实现这一点提出建议吗?
SELECT
p.id,
p.name,
GROUP_CONCAT(pc2.category_id, ',')
FROM product_category pc1
JOIN product_category pc2
JOIN product p
WHERE pc1.category_id = 1
AND pc1.product_id = pc2.product_id
AND p.id = pc1.product_id
GROUP BY pc1.product_id;
执行的是SqlFiddle,查询是
SELECT P.id AS product_id, P.name AS product_name,
GROUP_CONCAT(PC2.category_id) AS categories_id
FROM
product AS P LEFT JOIN product_category AS PC ON
P.id = PC.product_id LEFT JOIN product_category AS PC2 ON
P.id = PC2.product_id
WHERE PC.category_id = 1
GROUP BY P.id;