sql - 如何从Postgres中的嵌套估计中找到需要的 Material

标签 sql postgresql product postgresql-9.2 capacity-planning

产品估算包含子产品。 子产品也可以包含子产品等。 最后树叶contians Material 。 最大嵌套层数为 10。

订单还包含订购数量的产品、子产品和 Material 。 如何找到完成订单所需的 Material 需求?

产品、子产品和 Material 在单个表中:

create table toode (productid char(10) primary key );

估算表:

create table dok (
  dokumnr serial primary key,
  productid char(10) not null references toode
);

估算中的子产品和 Material :

create table rid (
  id serial primary key,
  dokumnr int not null references dok,
  itemid char(10) not null references toode,
  quantity  numeric(12,4) -- quantity required to make one product
);

订单:

create table orderrows (
  id serial primary key,
  itemid char(10) not null references toode,
  quantity  numeric(12,4)  -- ordered quantity
);

结果应该是查询返回 Material 和子产品的需求:

itemid char(10) not null references toode,
requiredquantity  numeric(12,4) -- total quantity of items required to make ordered products

如何在 Postgresql 9.2 中实现这个? 描述的字段应保留在这些表中。可以添加额外的 列和表,如果这有帮助。 是否可以进行一些适用于无限嵌套级别的通用查询。 还是创建将某些部分重复 10 次以获得最大 nensting 级别的查询的最佳方法?

更新

估计

product1
  material1  2 pcs
  subproduct2  3 pcs


subproduct2
  material2 4 pcs

被描述为

insert into dok values (1,'product1');
  insert into rid (dokumnr, itemid, quantity) values (1, 'material1', 2);
  insert into rid (dokumnr, itemid, quantity) values (1, 'subproduct2', 3);

insert into dok values (2,'subproduct2');
  insert into rid (dokumnr, itemid, quantity) values (2, 'material2', 4);

如果订购了 10 件产品 1,则描述为:

insert into orderrows (itemid, quantity ) values ('product1', 10);

结果应该是:

material1  20 
material2  120

material1数量计算为10*2

material2数量计算为10*3*4

更新 2

当最后一级包含不止一行时,Joachim 的回答给出了多级估计的错误结果。 Last join LEFT JOIN rid rid2 ON rid2.dokumnr = dok2.dokumnr 返回多行并且结果表是重复的。

测试用例 http://sqlfiddle.com/#!12/e5c11/1/0 :

create table toode (productid char(15) primary key );

create table dok (
  dokumnr serial primary key,
  productid char(15) not null references toode
);

create table rid (
  id serial primary key,
  dokumnr int not null references dok,
  itemid char(15) not null references toode,
  quantity  numeric(12,4) -- quantity required to make one product
);

create table orderrows (
  id serial primary key,
  itemid char(15) not null references toode,
  quantity  numeric(12,4)  -- ordered quantity
);

INSERT INTO toode VALUES ('product1'),('material1'),('subproduct2'), ('material2'), ('material3');
insert into dok values (1,'product1');
insert into dok values (2,'subproduct2');

insert into rid (dokumnr, itemid, quantity) values (1, 'material1', 1);
insert into rid (dokumnr, itemid, quantity) values (1, 'subproduct2', 1);
insert into rid (dokumnr, itemid, quantity) values (2, 'material2', 1);
insert into rid (dokumnr, itemid, quantity) values (2, 'material3', 1);

insert into orderrows (itemid, quantity ) values ('product1', 1);

预期:

每个数量都是 1,所以每个 Material 的结果数量必须是 1。

观察到:

Material2 和 matererial3 行重复。

如何解决这个问题?查询应确定叶节点本身。叶节点在数据中没有特别标注。

最佳答案

这应该使用递归查询来完成;

WITH RECURSIVE t(itemid,qty) AS (
  SELECT itemid,quantity,false isleaf FROM orderrows
  UNION ALL
  SELECT rid.itemid,(rid.quantity*t.qty)::NUMERIC(12,4),
         dok2.productid IS NULL
  FROM t 
  JOIN dok ON dok.productid=t.itemid
  JOIN rid ON rid.dokumnr=dok.dokumnr
  LEFT JOIN dok dok2 ON dok2.productid=rid.itemid
)
SELECT itemid, SUM(qty) FROM t WHERE isleaf GROUP BY itemid

An SQLfiddle to test with .

关于sql - 如何从Postgres中的嵌套估计中找到需要的 Material ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18040407/

相关文章:

postgresql - 我如何处理密码和 dockerfiles?

Magento 添加相关产品

java - 使用 jooq 选择条件

sql - 在 Ruby、Activerecord 或 Postgresql 中按周对事件进行分组和计数

python - 如何在 Python 中使用可选参数正确执行 SQL 查询?

postgresql - 表 xxx 上的 UPDATE 语句预期更新 1 行; 0 个与 Zope transactionmanager 匹配

php - 在 WooCommerce 中隐藏缺货相关产品

php - 仅显示产品分类的第一个和最后一个术语

php - 从 mysql 数据库回显特定行

sql - Postgres中负数之前的第一个正数的行?