这道sql题,有点棘手

题目:

 

(1).前置条件:

有以下数据集c和e,表查询结果如下图所示。

数据集c表为:test_medicine_buy

数据集e表为:test_medicine_sold

test_medicine_buy表数据:

 

 

 

test_medicine_sold表数据:

 

 

 

(2).题目要求:

如上图的数据集c和e,某医院系统卖给患者阿莫西林X数量后去下购进记录的库存,购进记录可能是零散的。

现在按 iilszh 排序,优先 iilszh 小的,依次下库存如何得到类似下面预期结果的结果集。

预期结果:

 

 

 

解题思路:

(1). 子查询a, 按照 spmc 药品名称进行分组,按 iilszh 正序排列,求得至当前记录的累计 gjsl

查询结果如下:

iilszh      spmc       gjsl   cum_gjsl
1        阿莫西林胶囊    20    20
2       阿莫西林胶囊    50    70
3       阿莫西林胶囊    40    110
4       阿莫西林胶囊    30    140
5       人血白蛋白    120        120
6       人血白蛋白      80     200
7       人血白蛋白      100    300

 


(2). 子查询c 为子查询a 与数据集e 在 join 后的结果

查询结果如下:

iilszh    spmc         gjsl      cum_gjsl      fysl
1      阿莫西林胶囊      20       20           80
2      阿莫西林胶囊     50       70         80
3      阿莫西林胶囊     40           110          80
4      阿莫西林胶囊     30       140          80
5      人血白蛋白      120      120         100
6      人血白蛋白        80       200         100
7      人血白蛋白        100      300         100

 


(3). 子查询d,每行累计购进数量总和减去总发药数量,求得diff_sl

查询结果如下:

iilszh    spmc        gjsl      cum_gjsl      fysl      diff_sl
1      阿莫西林胶囊     20       20           80       -60
2     阿莫西林胶囊     50       70            80       -10
3     阿莫西林胶囊     40       110           80       30
4     阿莫西林胶囊     30          140         80        60
5     人血白蛋白        120         120          100        20
6     人血白蛋白      80      200         100        100
7     人血白蛋白      100     300         100        200
(4). 针对子查询d 的查询结果作 case when 判断,最后得出满足需求的结果集,如预期结果栏数据

 

解题方式一:

适用于无需创建物理表的情况下

使用数据集c、e替代物理表:test_medicine_buy和test_medicine_sold,直接复制以下 hive sql 语句,可以在 Apache Hive 环境直接运行,得到以上预期结果数据。

SELECT spmc AS medicine_name,
gjsl AS buy_amount,
(gjsl - (CASE WHEN diff_sl < 0 THEN 0
WHEN diff_sl > gjsl THEN gjsl
ELSE diff_sl END)) AS this_cut_amount,
CASE WHEN diff_sl < 0 THEN 0
WHEN diff_sl > gjsl THEN gjsl
ELSE diff_sl END left_amount
FROM(
SELECT *,(cum_gjsl - fysl) AS diff_sl
FROM (
SELECT a.*,b.fysl
FROM (SELECT *,SUM(gjsl) OVER (PARTITION BY spmc ORDER BY iilszh) AS cum_gjsl
FROM ( select 1 iilszh,'阿莫西林胶囊' spmc,20 gjsl
union all
select 2 iilszh,'阿莫西林胶囊' spmc,50 gjsl
union all
select 3 iilszh,'阿莫西林胶囊' spmc,40 gjsl
union all
select 4 iilszh,'阿莫西林胶囊' spmc,30 gjsl
union all
select 5 iilszh,'人血白蛋白' spmc,120 gjsl
union all
select 6 iilszh,'人血白蛋白' spmc,80 gjsl
union all
select 7 iilszh,'人血白蛋白' spmc,100 gjsl
)c ORDER BY iilszh
) a
JOIN (SELECT spmc, fysl
FROM ( select 1 iilszh,'阿莫西林胶囊' spmc,80 fysl
union all
select 2 iilszh, '人血白蛋白' spmc,100 fysl
)e
) b ON a.spmc = b.spmc
) c ORDER BY iilszh, diff_sl) d

 


解题方式二:

适用于需先创建物理表:test_medicine_buy 和 test_medicine_sold 的情况下

将测试数据 insert 至 test_medicine_buy 和 test_medicine_sold 表。

表数据结果同前置条件中的 test_medicine_buy 和 test_medicine_sold 表数据。

将解题方式一中的数据集c,e 替换成表 test_medicine_buy 和test_medicine_sold 即可。

SELECT spmc AS medicine_name,
gjsl AS buy_amount,
(gjsl - (CASE WHEN diff_sl < 0 THEN 0
WHEN diff_sl > gjsl THEN gjsl
ELSE diff_sl END)) AS this_cut_amount,
CASE WHEN diff_sl < 0 THEN 0
WHEN diff_sl > gjsl THEN gjsl
ELSE diff_sl END left_amount
FROM(
SELECT *,(cum_gjsl - fysl) AS diff_sl
FROM (
SELECT a.*,b.fysl
FROM (SELECT *,SUM(gjsl) OVER (PARTITION BY spmc ORDER BY iilszh) AS cum_gjsl
FROM test_medicine_buy c ORDER BY iilszh
) a
JOIN (SELECT spmc, fysl
FROM test_medicine_sold e
) b ON a.spmc = b.spmc
) c ORDER BY iilszh, diff_sl) d

 


知识点归纳:

使用 hive sql 完成这道 Sql 题,所使用到的函数或方法如下:

SUM(gjsl) OVER (PARTITION BY spmc ORDER BY iilszh) AS cum_gjsl
PARTITION BY spmc ORDER BY iilszh:

 

使用spmc分组, iilszh字段正序排列后求gisl的总和;

(cum_gjsl - fysl) AS diff_sl:

 

通过spmc分组后的购进总量减去已发药数据,求取差值,作为上面case when的判断条件;

 

计算本次应下的库存

(gjsl - (CASE WHEN diff_sl < 0 THEN 0
WHEN diff_sl > gjsl THEN gjsl
ELSE diff_sl END)) AS this_cut_amount

 


计算本次剩余库存

CASE WHEN diff_sl < 0 THEN 0
WHEN diff_sl > gjsl THEN gjsl
ELSE diff_sl END left_amount

 


欢迎关注【无量测试之道】公众号,回复【领取资源】

Python+Unittest框架API自动化、

Python+Unittest框架API自动化、

Python+Pytest框架API自动化、

Python+Pandas+Pyecharts大数据分析、

Python+Selenium框架Web的UI自动化、

Python+Appium框架APP的UI自动化、

Python编程学习资源干货、

Vue前端组件化框架开发、

资源和代码 免费送啦~
文章下方有公众号二维码,可直接微信扫一扫关注即可。

备注:我的个人公众号已正式开通,致力于IT互联网技术的分享。

包含:数据分析、大数据、机器学习、测试开发、API接口自动化、测试运维、UI自动化、性能测试、代码检测、编程技术等。

微信搜索公众号:“无量测试之道”,或扫描下方二维码:

 

添加关注,让我们一起共同成长!

posted on 2022-06-16 19:58  Wu_Candy  阅读(51)  评论(0编辑  收藏  举报