Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/database/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 递归选择和联接相关表_Sql_Database_Postgresql_Recursive Query - Fatal编程技术网

Sql 递归选择和联接相关表

Sql 递归选择和联接相关表,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

我有两张像上面这样的桌子, 产品类别是层次结构, 和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 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
;