-
需求描述:
-
SQL求解
--构造商品库存测试数据
postgres=# CREATE TABLE tbl1 (
postgres(# isbn character varying(32),
postgres(# stock integer,
postgres(# vendor integer
postgres(# );
CREATE TABLE
postgres=# COMMENT ON TABLE tbl1 IS '商品库存表';
COMMENT
postgres=# COMMENT ON COLUMN tbl1.isbn IS '商品isbn';
COMMENT
postgres=# COMMENT ON COLUMN tbl1.stock IS '商品库存数量';
COMMENT
postgres=# COMMENT ON COLUMN tbl1.vendor IS '供货商ID';
COMMENT
postgres=# INSERT INTO tbl1 (isbn, stock, vendor) VALUES ('9787118078817', 1, 9);
INSERT 0 1
postgres=# INSERT INTO tbl1 (isbn, stock, vendor) VALUES ('9787118078817', 2, 7);
INSERT 0 1
postgres=# INSERT INTO tbl1 (isbn, stock, vendor) VALUES ('9787512108004', 2, 7);
INSERT 0 1
postgres=# INSERT INTO tbl1 (isbn, stock, vendor) VALUES ('9787512108004', 5, 9);
INSERT 0 1
postgres=# INSERT INTO tbl1 (isbn, stock, vendor) VALUES ('9787536473386', 2, 7);
INSERT 0 1
postgres=# INSERT INTO tbl1 (isbn, stock, vendor) VALUES ('9787530660560', 2, 7);
INSERT 0 1
postgres=# INSERT INTO tbl1 (isbn, stock, vendor) VALUES ('9787530660560', 7, 8);
INSERT 0 1
postgres=# INSERT INTO tbl1 (isbn, stock, vendor) VALUES ('9787530660560', 8, 10);
INSERT 0 1
postgres=# SELECT * FROM tbl1;
isbn | stock | vendor
---------------+-------+--------
9787118078817 | 1 | 9
9787118078817 | 2 | 7
9787512108004 | 2 | 7
9787512108004 | 5 | 9
9787536473386 | 2 | 7
9787530660560 | 2 | 7
9787530660560 | 7 | 8
9787530660560 | 8 | 10
(8 rows)
--构造商品销售测试数据
postgres=# CREATE TABLE tbl2 (
postgres(# isbn character varying(32),
postgres(# stock integer
postgres(# );
CREATE TABLE
postgres=# COMMENT ON TABLE tbl2 IS '商品销售表';
COMMENT
postgres=# COMMENT ON COLUMN tbl2.isbn IS '商品isbn';
COMMENT
postgres=# COMMENT ON COLUMN tbl2.stock IS '商品销售数量';
COMMENT
postgres=# INSERT INTO tbl2 (isbn, stock) VALUES ('9787118078817', 2);
INSERT 0 1
postgres=# INSERT INTO tbl2 (isbn, stock) VALUES ('9787536473386', 2);
INSERT 0 1
postgres=# INSERT INTO tbl2 (isbn, stock) VALUES ('9787530660560', 5);
INSERT 0 1
postgres=# SELECT * FROM tbl2;
isbn | stock
---------------+-------
9787118078817 | 2
9787536473386 | 2
9787530660560 | 5
(3 rows)
postgres=# WITH recursive tmp AS --首先根据商品isbn和库存构造出一个棵查询树,为递归做准备
postgres-# (SELECT t.isbn,
postgres(# t.stock,
postgres(# t.vendor,
postgres(# t.stock2,
postgres(# t.isbn || '_' || top v_id, --构建虚拟主键ID
postgres(# t.isbn || '_' || LAG(top, 1, NULL) OVER(PARTITION BY t.isbn ORDER BY t.stock) v_pid --构建虚拟父节点ID
postgres(# FROM (SELECT t1.isbn,
postgres(# t1.stock,
postgres(# t1.vendor,
postgres(# t2.stock stock2,
postgres(# row_number() over(PARTITION BY t1.isbn ORDER BY t1.stock) top
postgres(# FROM tbl1 t1,
postgres(# tbl2 t2
postgres(# WHERE t1.isbn = t2.isbn)t ),
postgres-# x AS
postgres-# (SELECT t.isbn,
postgres(# CASE
postgres(# WHEN t.stock - t.stock2 <= 0 THEN
postgres(# 0
postgres(# ELSE
postgres(# t.stock - t.stock2
postgres(# END stock,
postgres(# t.vendor,
postgres(# (t.stock2 - t.stock) stock2,
postgres(# t.v_id,
postgres(# t.v_pid
postgres(# FROM tmp t
postgres(# WHERE t.v_pid IS NULL --从每个商品最小的库存行开始递归
postgres(# UNION ALL
postgres(# SELECT tmp.isbn,
postgres(# CASE
postgres(# WHEN tmp.stock - x.stock2 <= 0 THEN --如果当前供应商的库存小于销售量,则标记当前供应商的库存为0
postgres(# 0
postgres(# WHEN x.stock2 < 0 THEN --如果当前销售量为负数,说明前一个节点的库存已大于销售,那么库存无需再减
postgres(# tmp.stock
postgres(# ELSE
postgres(# tmp.stock - x.stock2 --库存-销量=剩余库存
postgres(# END stock,
postgres(# tmp.vendor,
postgres(# (x.stock2 - tmp.stock) stock2, --销量-库存=多出的销量
postgres(# tmp.v_id,
postgres(# tmp.v_pid
postgres(# FROM x,
postgres(# tmp
postgres(# WHERE x.v_id = tmp.v_pid)
postgres-# SELECT isbn,stock,vendor FROM x WHERE stock != 0 --过滤掉为0库存的供应商数据
postgres-# UNION ALL --此部分数据为没有销售过的商品数据,直接返回即可
postgres-# SELECT t1.isbn,
postgres-# t1.stock,
postgres-# t1.vendor
postgres-# FROM tbl1 t1
postgres-# LEFT JOIN tbl2 t2
postgres-# ON t1.isbn = t2.isbn
postgres-# WHERE t2.isbn IS NULL;
isbn | stock | vendor
---------------+-------+--------
9787118078817 | 1 | 7 --销量为2,按照库存从低到高依次减销量,直到销量全部减完
9787530660560 | 4 | 8
9787530660560 | 8 | 10
9787512108004 | 2 | 7
9787512108004 | 5 | 9
(5 rows)
复制
最后修改时间:2022-03-07 17:36:37
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。
评论
相关阅读
玩一玩系列——玩玩pg_mooncake(PostgreSQL的高性能列存新贵)
小满未满、
507次阅读
2025-03-03 17:18:03
王炸!OGG 23ai 终于支持从PostgreSQL备库抽取数据了
曹海峰
385次阅读
2025-03-09 12:54:06
玩一玩系列——玩玩login_hook(一款即将停止维护的PostgreSQL登录插件)
小满未满、
371次阅读
2025-03-08 18:19:28
明明想执行的SQL是DELETE、UPDATE,但为什么看到的是SELECT(FDW的实现原理解析)
小满未满、
344次阅读
2025-03-19 23:11:26
PostgreSQL初/中/高级认证考试(3.15)通过考生公示
开源软件联盟PostgreSQL分会
294次阅读
2025-03-20 09:50:36
IvorySQL 4.4 发布 - 基于 PostgreSQL 17.4,增强平台支持
通讯员
181次阅读
2025-03-20 15:31:04
套壳论
梧桐
176次阅读
2025-03-09 10:58:17
命名不规范,事后泪两行
xiongcc
164次阅读
2025-03-13 14:26:08
版本发布| IvorySQL 4.4 发布
IvorySQL开源数据库社区
110次阅读
2025-03-13 09:52:33
宝藏PEV,助力你成为SQL优化高手
xiongcc
98次阅读
2025-03-09 23:34:23