递归 select 并加入相关 table
recursive select and join related table
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")
);
我有两个像上面的table,
product_category
是层次结构,
和 product.product_category_id
fk product_category.id
。
如何 select 特定 product_category id 下的所有产品,
例如
如果输入 product_category 1,
输出 -> product:1, product:2
如果输入product_category 2
输出 -> product: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
查询
像这样??但是这个 return 只有 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 =
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)
注意:我的系统上没有安装 postgresql,所以我是基于概念来讨论的。我没有看到你在哪里定义了外键约束......我仍然假设你已经这样做了。而且我还没有检查 CTE/Common Table 表达式的正确性(- 基本上是 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
);
您应该首先建立类别列表,然后将其加入产品。
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
;
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")
);
我有两个像上面的table,
product_category
是层次结构,
和 product.product_category_id
fk product_category.id
。
如何 select 特定 product_category id 下的所有产品,
例如
如果输入 product_category 1,
输出 -> product:1, product:2
如果输入product_category 2
输出 -> product: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
查询
像这样??但是这个 return 只有 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 =
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)
注意:我的系统上没有安装 postgresql,所以我是基于概念来讨论的。我没有看到你在哪里定义了外键约束......我仍然假设你已经这样做了。而且我还没有检查 CTE/Common Table 表达式的正确性(- 基本上是 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
);
您应该首先建立类别列表,然后将其加入产品。
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
;