[英]How do I group data in Oracle SQL without using GROUP BY OR PARTITION BY
My data is like this我的数据是这样的
MY_TABLE MY_TABLE
DATE![]() |
CUSTOMER_ID![]() |
FAC_NUM ![]() |
MONIES![]() |
---|---|---|---|
01/Jan/2020 ![]() |
12345678 ![]() |
ABC123 ![]() |
125000 ![]() |
02/Jan/2020 ![]() |
12345678 ![]() |
ABC123 ![]() |
125000 ![]() |
03/Jan/2020 ![]() |
12345678 ![]() |
ABC123 ![]() |
125000 ![]() |
01/Feb/2020 ![]() |
12345678 ![]() |
ABC123 ![]() |
143000 ![]() |
02/Feb/2020 ![]() |
12345678 ![]() |
ABC123 ![]() |
143000 ![]() |
03/Feb/2020 ![]() |
12345678 ![]() |
ABC123 ![]() |
143000 ![]() |
04/Feb/2020 ![]() |
12345678 ![]() |
ABC123 ![]() |
143000 ![]() |
05/Feb/2020 ![]() |
12345678 ![]() |
ABC123 ![]() |
143000 ![]() |
01/Mar/2020 ![]() |
12345678 ![]() |
ABC123 ![]() |
125000 ![]() |
02/Mar/2020 ![]() |
12345678 ![]() |
ABC123 ![]() |
125000 ![]() |
03/Mar/2020 ![]() |
12345678 ![]() |
ABC123 ![]() |
125000 ![]() |
04/Mar/2020 ![]() |
12345678 ![]() |
ABC123 ![]() |
125000 ![]() |
I want the output to be like this我希望 output 是这样的
CUSTOMER_ID![]() |
FAC_NUM ![]() |
MONIES![]() |
START_DATE![]() |
END_DATE![]() |
---|---|---|---|---|
12345678 ![]() |
ABC123 ![]() |
125000 ![]() |
01/Jan/2020 ![]() |
03/JAN/2020 ![]() |
12345678 ![]() |
ABC123 ![]() |
143000 ![]() |
01/Feb/2020 ![]() |
05/Feb/2020 ![]() |
12345678 ![]() |
ABC123 ![]() |
125000 ![]() |
01/Mar/2020 ![]() |
04/Mar/2020 ![]() |
I have tried using the following我试过使用以下
SELECT CUSTOMER_ID
,FAC_NUM
,MONIES
,MIN(DATE) AS START_DATE
,MAX(DATE) AS END_DATE
FROM MY_TABLE
GROUP BY CUSTOMER_ID
,FAC_NUM
,MONIES
However, the output I get with this approach is as follows (this is not the desired output)但是,我用这种方法得到的 output 如下(这不是所需的输出)
CUSTOMER_ID![]() |
FAC_NUM ![]() |
MONIES![]() |
START_DATE![]() |
END_DATE![]() |
---|---|---|---|---|
12345678 ![]() |
ABC123 ![]() |
125000 ![]() |
1 Jan 2020 ![]() |
4 Mar 2020 ![]() |
12345678 ![]() |
ABC123 ![]() |
143000 ![]() |
1 Feb 2020 ![]() |
5 Feb 2020 ![]() |
Is there a way to obtain the output I am looking for without using PL/SQL (I need to run this query over a huge dataset)?有没有办法在不使用 PL/SQL 的情况下获得我正在寻找的 output(我需要在一个巨大的数据集上运行这个查询)? If not, what would be the most efficient way to do this using PL/SQL?
如果不是,那么使用 PL/SQL 执行此操作的最有效方法是什么?
I am new to stackoverflow and SQL.我是 stackoverflow 和 SQL 的新手。 Your support would be highly appreciated.
您的支持将不胜感激。
Thanks in advance for your help.在此先感谢您的帮助。
Regards, Ani问候, 阿尼
Instead of "I want output", it would probably helped if you described what you wanted.如果您描述了您想要的内容,而不是“我想要输出”,它可能会有所帮助。
To me, it looks as if you'd want to group additionally by month, eg your query slightly modified:对我来说,您似乎还想按月另外分组,例如您的查询稍作修改:
SELECT CUSTOMER_ID
,FAC_NUM
,MONIES
,MIN(DATE) AS START_DATE
,MAX(DATE) AS END_DATE
FROM MY_TABLE
GROUP BY CUSTOMER_ID
,FAC_NUM
,MONIES
, to_char(date, 'yyyymm') --> this
Of course, date
column name is invalid;当然,
date
列名是无效的; it is reserved for date
datatype so I presume it is, actually, named differently.它是为
date
数据类型保留的,所以我认为它实际上命名不同。
This reads like a gaps-and-islands problem.这听起来像是一个空白和孤岛问题。 Islands are adjacent rows having the same customer, fac num and amount.
岛是具有相同客户、面数和金额的相邻行。 Whenever the amount changes, a new group starts.
每当数量发生变化时,就会开始一个新的组。
Here is one approach using the difference between row numbers to identify the islands:这是一种使用行号之间的差异来识别岛屿的方法:
select customer_id, fac_num, monies,
min(date) as start_date, max(date) as end_date
from (
select t.*,
row_number() over(partition by customer_id, fac_num order by date) as rn1,
row_number() over(partition by customer_id, fac_num, monies order by date) as rn2
from mytable t
) t
group by customer_id, fac_num, monies, rn1 - rn2
order by customer_id, fac_num, min(start_date)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.