Sql 递归选择和联接相关表
我有两张像上面这样的桌子, 产品类别是层次结构, 和product.product_category_id fk product_category.id 如何选择特定产品类别id下的所有产品 e、 g 如果输入产品类别1, 输出->产品:1,产品:2Sql 递归选择和联接相关表,sql,database,postgresql,recursive-query,Sql,Database,Postgresql,Recursive Query,我有两张像上面这样的桌子, 产品类别是层次结构, 和product.product_category_id fk product_category.id 如何选择特定产品类别id下的所有产品 e、 g 如果输入产品类别1, 输出->产品:1,产品:2 CREATE TABLE IF NOT EXISTS "product_category"( "id" SERIAL NOT NULL, "parent_id" integer DEFAULT NULL, "name" varchar
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")
);
如果输入产品_类别2
输出->产品:2
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
id | parent_id | name
1 | | parent
2 | 1 | child
3 | 2 | child child
product
id | product_category_id
1 | 1
2 | 3
注意:我的系统上没有安装postgresql,所以我是根据概念进行讨论的。我看不到您在哪里定义了外键约束。。。但我还是认为你已经这样做了。我还没有检查CTE/公共表表达式的正确性——基本上是SQL的递归部分。假设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 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)
与
接下来我要检查的是CTE的正确性
因此,显然,以下措施应该奏效:
SELECT * FROM product WHERE product_category_id IN (SELECT * FROM pc)
您应该首先建立类别列表,然后将其加入到产品中
;
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
);
其中id=$1。。。在那一部分,请用pc替换id。id他们没有收到你的上一个/以上问题。我也没有尝试优化您的查询。让我重新发布,但这一次你的整个问题与我的最小编辑/更正。如果你还有问题,请告诉我。谢谢,放一个;前后的陈述都是无用的。你只需要一个;最后,Hi a_horse_with_no_name:根据您在postgresql中测试查询的状态,缺少first;可能会引起问题。。。基本上,当出于某种原因之前在psql中打印的语句true for mssql也没有以分号结尾时,这种情况会发生在公共表表达式中。为什么不亲自检查一下呢?谢谢这与CTE无关。每一份声明都需要以;在SQL或PSQL中,非常感谢,我明白了!!我应该在最后从pc选择*中添加p.product\u category\u id吗?因为我使用您的查询似乎选择了所有产品列表
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
;