CREATE TABLE IF NOT EXISTS "product_category"(
"id" SERIAL NOT NULL,
"parent_id" integer DEFAULT NULL,
"name" varchar DEFAULT NULL,
PRIMARY KEY ("id")
);
CREATE TABLE IF NOT EXISTS "product"(
"id" SERIAL NOT NULL,
"product_category_id" integer DEFAULT NULL,
PRIMARY KEY ("id")
);
我有两张上面的表,
product_category
是层次结构,
和product.product_category_id
fk product_category.id
。
如何选择特定product_category id下的所有产品,
e.g
如果输入product_category 1,
输出 - >产品:1,产品:2
如果输入product_category 2
输出 - >产品:2
product_category
id | parent_id | name
1 | | parent
2 | 1 | child
3 | 2 | child child
product
id | product_category_id
1 | 1
2 | 3
查询
像这样?但这只返回product_category列表....我想要产品列表WITH RECURSIVE pc AS (
SELECT pc.id AS id
FROM product_category pc
LEFT JOIN product p ON p.product_category_id = pc.id
WHERE id = $1
UNION ALL
SELECT child.id
FROM product_category AS child
LEFT JOIN product p ON p.product_category_id = child.id
JOIN pc ON pc.id = child.parent_id
)
SELECT * FROM product_category WHERE id IN (SELECT * FROM pc)
答案 0 :(得分:2)
您应首先建立类别列表,然后将其加入产品。
WITH RECURSIVE pc AS (
SELECT id
FROM product_category
WHERE id = $id
UNION ALL
SELECT child.id
FROM product_category AS child
JOIN pc ON pc.id = child.parent_id
)
SELECT pr.*
FROM product pr
JOIN pc on pr.product_category_id = pc.id
;
答案 1 :(得分:1)
注意:我的系统上没有安装postgresql,所以我基于概念进行讨论。我没有看到你在哪里定义了外键约束......我仍假设你已经这样做了。我还没有检查CTE /公用表表达式的正确性( - 基本上是SQL的递归部分)。 假设CTE正确 -
如何更换
SELECT * FROM product_category WHERE id IN (SELECT * FROM pc)
与
SELECT * FROM product WHERE product_category_id IN (SELECT * FROM pc)
接下来我要检查CTE的正确性。
显然以下情况应该有效:
;
WITH RECURSIVE pc AS (
SELECT pc.id AS id
FROM
product_category pc
LEFT JOIN product p
ON p.product_category_id = pc.id
WHERE pc.id = <Your product category id of interest>
UNION ALL
SELECT child.id
FROM
product_category AS child
LEFT JOIN product p
ON p.product_category_id = child.id
JOIN pc
ON pc.id = child.parent_id
)
SELECT id as product_id FROM product WHERE product_category_id
IN (
SELECT * FROM pc
);