问题描述
嗨,团队,
数据设置:
问题: 需要一个SQL查询,它将只在下面的行,
要求: 分区按item_name,item_price和order按时间和总和item_volume,无论总和将变为零,这些记录需要打印,如果我们看到下面的预期输出100,-100结果零和100,-75,-25结果零,所以只有那些记录需要。
数据设置:
create table test_item as with t1 as ( select 1 category, 'abc' Item_name,100 item_volume,12.3 item_price,to_date('04-may-2017 12:22:33 AM','dd-mon-yyyy hh:mi:ss AM') time from dual union select 1,'abc' ,-100 ,12.3 ,to_date('04-may-2017 12:22:34 AM','dd-mon-yyyy hh:mi:ss AM') from dual union select 1,'abc' ,200 ,12.3 ,to_date('04-may-2017 12:22:34 AM','dd-mon-yyyy hh:mi:ss AM') from dual union select 1,'abc' ,-100 ,12.3 ,to_date('04-may-2017 12:22:35 AM','dd-mon-yyyy hh:mi:ss AM') from dual union select 2 category, 'abcd' Item_name,100 item_volume,12.32 item_price,to_date('04-may-2017 12:22:33 AM','dd-mon-yyyy hh:mi:ss AM') time from dual union select 2,'abcd' ,-25 ,12.32 ,to_date('04-may-2017 12:22:34 AM','dd-mon-yyyy hh:mi:ss AM') from dual union select 2,'abcd' ,-75 ,12.32 ,to_date('04-may-2017 12:22:34 AM','dd-mon-yyyy hh:mi:ss AM') from dual union select 2,'abcd' ,100 ,12.32 ,to_date('04-may-2017 12:22:35 AM','dd-mon-yyyy hh:mi:ss AM') from dual ) select * from t1; -------------------------------------------------- CATEGORY ITEM ITEM_VOLUME ITEM_PRICE TO_CHAR(TIME,'DD-MON-YY ---------- ---- ----------- ---------- ----------------------- 1 abc 100 12.3 04-may-2017 12:22:33 am 1 abc -100 12.3 04-may-2017 12:22:34 am 1 abc 200 12.3 04-may-2017 12:22:34 am 1 abc -100 12.3 04-may-2017 12:22:35 am 2 abcd 100 12.32 04-may-2017 12:22:33 am 2 abcd -75 12.32 04-may-2017 12:22:34 am 2 abcd -25 12.32 04-may-2017 12:22:34 am 2 abcd 100 12.32 04-may-2017 12:22:35 am复制
问题: 需要一个SQL查询,它将只在下面的行,
要求: 分区按item_name,item_price和order按时间和总和item_volume,无论总和将变为零,这些记录需要打印,如果我们看到下面的预期输出100,-100结果零和100,-75,-25结果零,所以只有那些记录需要。
1 abc 100 12.3 04-MAY-17 1 abc -100 12.3 04-MAY-17 2 abcd 100 12.32 04-MAY-17 2 abcd -75 12.32 04-MAY-17 2 abcd -25 12.32 04-MAY-17复制
专家解答
因此,您希望找到每个类别的运行总数为零的行。然后显示它和它前面的所有行?如果运行总数可以在两个不同的场合达到零,会发生什么?
无论如何,这里有一个基本的算法:
1.计算每个类别的运行总数
2.按类别分配行号
3.查找运行总数最小的行的最高行编号
4.运行总数的最小值
做第一遍的前两个步骤:
您可以使用以下方法找到步骤3的值:
这是在说:
按 (运行) tot对行进行排序。然后,对于每个类别中运行总数最低的类别,找到最大行号。
在此之后,您需要做的就是确保最小运行总数为零,并找到行号等于或低于步骤3中的行号的所有行:
或者如果你想做12c风格,你可以使用match_recognize:
不过,这只会在运行总数第一次达到零时匹配。解析方法将匹配多个:
无论如何,这里有一个基本的算法:
1.计算每个类别的运行总数
2.按类别分配行号
3.查找运行总数最小的行的最高行编号
4.运行总数的最小值
做第一遍的前两个步骤:
select ti.*, sum(item_volume) over (partition by category order by time, item_volume) tot, row_number() over (partition by category order by time, item_volume) rn from test_item ti;复制
您可以使用以下方法找到步骤3的值:
max(rn) keep (dense_rank first order by tot) over (partition by category)复制
这是在说:
按 (运行) tot对行进行排序。然后,对于每个类别中运行总数最低的类别,找到最大行号。
在此之后,您需要做的就是确保最小运行总数为零,并找到行号等于或低于步骤3中的行号的所有行:
create table test_item as with t1 as ( select 1 category, 'abc' Item_name,100 item_volume,12.3 item_price,to_date('04-may-2017 12:22:33 AM','dd-mon-yyyy hh:mi:ss AM') time from dual union select 1,'abc' ,-100 ,12.3 ,to_date('04-may-2017 12:22:34 AM','dd-mon-yyyy hh:mi:ss AM') from dual union select 1,'abc' ,200 ,12.3 ,to_date('04-may-2017 12:22:34 AM','dd-mon-yyyy hh:mi:ss AM') from dual union select 1,'abc' ,-100 ,12.3 ,to_date('04-may-2017 12:22:35 AM','dd-mon-yyyy hh:mi:ss AM') from dual union select 2 category, 'abcd' Item_name,100 item_volume,12.32 item_price,to_date('04-may-2017 12:22:33 AM','dd-mon-yyyy hh:mi:ss AM') time from dual union select 2,'abcd' ,-25 ,12.32 ,to_date('04-may-2017 12:22:34 AM','dd-mon-yyyy hh:mi:ss AM') from dual union select 2,'abcd' ,-75 ,12.32 ,to_date('04-may-2017 12:22:34 AM','dd-mon-yyyy hh:mi:ss AM') from dual union select 2,'abcd' ,100 ,12.32 ,to_date('04-may-2017 12:22:35 AM','dd-mon-yyyy hh:mi:ss AM') from dual union select 3,'def' ,100 ,12.32 ,to_date('04-may-2017 12:22:34 AM','dd-mon-yyyy hh:mi:ss AM') from dual union select 3,'def' ,50 ,12.32 ,to_date('04-may-2017 12:22:35 AM','dd-mon-yyyy hh:mi:ss AM') from dual ) select * from t1; with tots as ( select ti.*, sum(item_volume) over (partition by category order by time, item_volume) tot, row_number() over (partition by category order by time, item_volume) rn from test_item ti ), rws as ( select t.*, max(rn) keep (dense_rank first order by tot) over (partition by category) mxrn , min(tot) over (partition by category) mn from tots t ) select * from rws where rn <= mxrn and mn = 0 order by 1, 5; CATEGORY ITEM_NAME ITEM_VOLUME ITEM_PRICE TIME TOT RN MXRN MN 1 abc 100 12.3 04-MAY-2017 00:22:33 100 1 2 0 1 abc -100 12.3 04-MAY-2017 00:22:34 0 2 2 0 2 abcd 100 12.32 04-MAY-2017 00:22:33 100 1 3 0 2 abcd -75 12.32 04-MAY-2017 00:22:34 25 2 3 0 2 abcd -25 12.32 04-MAY-2017 00:22:34 0 3 3 0复制
或者如果你想做12c风格,你可以使用match_recognize:
select * from test_item match_recognize ( partition by category order by time, item_volume measures classifier() c all rows per match pattern (running* zero) define zero as sum(running.item_volume) = 0 ) where c = 'RUNNING'; CATEGORY TIME ITEM_VOLUME C ITEM_NAME ITEM_PRICE 1 04-MAY-2017 00:22:33 100 RUNNING abc 12.3 1 04-MAY-2017 00:22:34 -100 RUNNING abc 12.3 2 04-MAY-2017 00:22:33 100 RUNNING abcd 12.32 2 04-MAY-2017 00:22:34 -75 RUNNING abcd 12.32 2 04-MAY-2017 00:22:34 -25 RUNNING abcd 12.32复制
不过,这只会在运行总数第一次达到零时匹配。解析方法将匹配多个:
insert into test_item select 1,'abc' ,-100 ,12.3 ,to_date('04-may-2017 12:22:35 AM','dd-mon-yyyy hh:mi:ss AM') from dual; select * from test_item match_recognize ( partition by category order by time, item_volume measures classifier() c all rows per match pattern (running* zero) define zero as sum(running.item_volume) = 0 ) where c = 'RUNNING'; CATEGORY TIME ITEM_VOLUME C ITEM_NAME ITEM_PRICE 1 04-MAY-2017 00:22:33 100 RUNNING abc 12.3 1 04-MAY-2017 00:22:34 -100 RUNNING abc 12.3 2 04-MAY-2017 00:22:33 100 RUNNING abcd 12.32 2 04-MAY-2017 00:22:34 -75 RUNNING abcd 12.32 2 04-MAY-2017 00:22:34 -25 RUNNING abcd 12.32 with tots as ( select ti.*, sum(item_volume) over (partition by category order by time, item_volume) tot, row_number() over (partition by category order by time, item_volume) rn from test_item ti ), rws as ( select t.*, max(rn) keep (dense_rank first order by tot) over (partition by category) mxrn , min(tot) over (partition by category) mn from tots t ) select * from rws where rn <= mxrn and mn = 0 order by 1, 5; CATEGORY ITEM_NAME ITEM_VOLUME ITEM_PRICE TIME TOT RN MXRN MN 1 abc 100 12.3 04-MAY-2017 00:22:33 100 1 5 0 1 abc -100 12.3 04-MAY-2017 00:22:34 0 2 5 0 1 abc 200 12.3 04-MAY-2017 00:22:34 200 3 5 0 1 abc -100 12.3 04-MAY-2017 00:22:35 0 4 5 0 1 abc -100 12.3 04-MAY-2017 00:22:35 0 5 5 0 2 abcd 100 12.32 04-MAY-2017 00:22:33 100 1 3 0 2 abcd -75 12.32 04-MAY-2017 00:22:34 25 2 3 0 2 abcd -25 12.32 04-MAY-2017 00:22:34 0 3 3 0复制
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。
评论
相关阅读
Oracle RAC 一键安装翻车?手把手教你如何排错!
Lucifer三思而后行
601次阅读
2025-04-15 17:24:06
【纯干货】Oracle 19C RU 19.27 发布,如何快速升级和安装?
Lucifer三思而后行
587次阅读
2025-04-18 14:18:38
XTTS跨版本迁移升级方案(11g to 19c RAC for Linux)
zwtian
494次阅读
2025-04-08 09:12:48
Oracle数据库一键巡检并生成HTML结果,免费脚本速来下载!
陈举超
478次阅读
2025-04-20 10:07:02
【ORACLE】记录一些ORACLE的merge into语句的BUG
DarkAthena
463次阅读
2025-04-22 00:20:37
Oracle 19c RAC更换IP实战,运维必看!
szrsu
439次阅读
2025-04-08 23:57:08
【ORACLE】你以为的真的是你以为的么?--ORA-38104: Columns referenced in the ON Clause cannot be updated
DarkAthena
437次阅读
2025-04-22 00:13:51
【活动】分享你的压箱底干货文档,三篇解锁进阶奖励!
墨天轮编辑部
428次阅读
2025-04-17 17:02:24
火焰图--分析复杂SQL执行计划的利器
听见风的声音
371次阅读
2025-04-17 09:30:30
3月“墨力原创作者计划”获奖名单公布
墨天轮编辑部
360次阅读
2025-04-15 14:48:05