数据块聚合

2020-09-12 04:51发布

         点击此处--->   EasySAP.com群内免费提供SAP练习系统(在群公告中)

加入QQ群:457200227(SAP S4 HANA技术交流) 群内免费提供SAP练习系统(在群公告中)


嗨,

我想实现一个解决方案,其中我有一个如下所示的数据集-

我想基于lat-long聚合数据,如果一行中发送了相同的lat-long,则这些行应进行聚合并返回到单行中。 以下是我期望的输出-

但是,这里的问题是,如果在以后的某个时间点再次发送了经纬度组合,则不应对其进行汇总。 为此,它应该有一个新行(例如s_no 1和5的行具有相同的经纬度,但不进行汇总。

我使用循环实现了该解决方案,但是由于数据集很大,因此性能很差。

有人可以为此建议一个更好的解决方案(不包括循环/光标)吗?

下面是创建表和插入数据的sql查询-

创建表dev_tab(id nvarchar(10),lat十进制(12,9),long十进制(12,9),时间戳记timestamp);

插入dev_tab(id,lat,long,timestamp)值('g1',48.762438,9.186757,'2018-09-11 07:00:00');

插入dev_tab(id,lat,long,timestamp)值('g1',48.762438,9.186757,'2018-09-11 10:00:00');

插入dev_tab(id,lat,long,timestamp)值('g1',46.943718,8.999521,'2018-09-11 14:00:00');

插入dev_tab(id,lat,long,timestamp)值('g1',44.291991,0.938082,'2018-09-12 05:00:00');

插入dev_tab(id,lat,long,timestamp)值('g1',44.291991,0.938082,'2018-09-12 07:00:00');

插入dev_tab(id,lat,long,timestamp)值('g1',12.885067,77.553435,'2018-09-12 08:00:00');

插入dev_tab(id,lat,long,timestamp)值('g1',48.762438,9.186757,'2018-09-13 10:00:00');


谢谢。

致谢,
普拉奇

(11.4 kB)

         点击此处--->   EasySAP.com群内免费提供SAP练习系统(在群公告中)

加入QQ群:457200227(SAP S4 HANA技术交流) 群内免费提供SAP练习系统(在群公告中)


嗨,

我想实现一个解决方案,其中我有一个如下所示的数据集-

我想基于lat-long聚合数据,如果一行中发送了相同的lat-long,则这些行应进行聚合并返回到单行中。 以下是我期望的输出-

但是,这里的问题是,如果在以后的某个时间点再次发送了经纬度组合,则不应对其进行汇总。 为此,它应该有一个新行(例如s_no 1和5的行具有相同的经纬度,但不进行汇总。

我使用循环实现了该解决方案,但是由于数据集很大,因此性能很差。

有人可以为此建议一个更好的解决方案(不包括循环/光标)吗?

下面是创建表和插入数据的sql查询-

创建表dev_tab(id nvarchar(10),lat十进制(12,9),long十进制(12,9),时间戳记timestamp);

插入dev_tab(id,lat,long,timestamp)值('g1',48.762438,9.186757,'2018-09-11 07:00:00');

插入dev_tab(id,lat,long,timestamp)值('g1',48.762438,9.186757,'2018-09-11 10:00:00');

插入dev_tab(id,lat,long,timestamp)值('g1',46.943718,8.999521,'2018-09-11 14:00:00');

插入dev_tab(id,lat,long,timestamp)值('g1',44.291991,0.938082,'2018-09-12 05:00:00');

插入dev_tab(id,lat,long,timestamp)值('g1',44.291991,0.938082,'2018-09-12 07:00:00');

插入dev_tab(id,lat,long,timestamp)值('g1',12.885067,77.553435,'2018-09-12 08:00:00');

插入dev_tab(id,lat,long,timestamp)值('g1',48.762438,9.186757,'2018-09-13 10:00:00');


谢谢。

致谢,
普拉奇

(11.4 kB)
付费偷看设置
发送
4条回答
闻人可可
1楼 · 2020-09-12 05:08.采纳回答

感谢您输入一些测试数据; 这样就可以解决这个问题。

您在这里遇到的是一个经典的SQL问题,通常称为"孤岛和差距问题"。

我建议您仔细阅读,因为有几种不同的方法各有利弊。 Google是您的朋友,或者只是索取Joe Celko的历史悠久的经典著作" SQL for smarties"(如果您的工作经常涉及编写SQL,那么您应该拥有这本书。)

对于这个问题,我只是采用google-it方法,然后找到了以下页面: https://www.red-gate.com/simple-talk/sql/t-sql-programming/the-sql-of 序列中的空缺和岛屿/

是的,它是关于MS SQL Server的,不是的,我不在乎,因为该原理在大多数基于SQL的DBMS(例如HANA)中都起作用。


我用您的数据建立了一个表:

选择id,lat,long,timestamp
 来自dev_tab
 按时间戳排序;

/*
 ID LAT LONG TIMESTAMP
 g1 48.762438 9.186757 11/09/2018 7:00:00.0 AM
 g1 48.762438 9.186757 11/09/2018 10:00:00.0 AM
 g1 46.943718 8.999521 11/09/2018 2:00:00.0 PM
 g1 44.291991 0.938082 12/09/2018 5:00:00.0 AM
 g1 44.291991 0.938082 12/09/2018 7:00:00.0 AM
 g1 12.885067 77.553435 12/09/2018 8:00:00.0 AM
 g1 48.762438 9.186757 13/09/2018 10:00:00.0 AM
 */
 

然后按照示例进行操作。 基本上,方法是找到组的"边界"(请参阅​​"起点"和"终点"查询),然后将这两个集合合并。

,src为(选择id,lat,long,timestamp
                   ,将row_number()结束(按时间戳排序)为seq
 来自dev_tab
 按时间戳排序
              ),
 起点为(
     选择id,seq,lat,long,timestamp,row_number()作为rownum(按seq排序)
     来自srcsrc_a
     不存在的地方(
                        选择 *
                        来自srcsrc_b
                        其中(src_b.lat,src_b.long)=(src_a.lat,src_b.long)
                        和src_b.seq = src_A.seq-1
                        )
     ),
 端点为(
     选择id,seq,lat,long,timestamp,row_number()作为rownum(按seq排序)
     来自srcsrc_a
     不存在的地方(
                        选择 *
                        来自srcsrc_b
                        其中(src_b.lat,src_b.long)=(src_a.lat,src_b.long)
                        和src_b.seq = src_A.seq + 1
                        )
     )
 选择
      s.id,s.seq,s.lat,s.long,s.timestamp作为start_timestamp,e.timestamp作为end_timestamp
 从起点
 左外连接端点e
 on(s.lat,s.long)=(e.lat,e.long)
 和s.rownum = e.rownum;
 
 ID SEQ LAT LONG START_TIMESTAMP END_TIMESTAMP
 g1 1 48.762438 9.186757 11/09/2018 7:00:00.0 AM 11/09/2018 10:00:00.0 AM
 g1 3 46.943718 8.999521 11/09/2018 2:00:00.0 PM 11/09/2018 2:00:00.0 PM
 g1 4 44.291991 0.938082 12/09/2018 5:00:00.0 AM 12/09/2018 7:00:00.0 AM
 g1 6 12.885067 77.553435 12/09/2018 8:00:00.0 AM 12/09/2018 8:00:00.0 AM
 g1 7 48.762438 9.186757 13/09/2018 10:00:00.0 AM 13/09/2018 10:00:00.0 AM
 

结果几乎是您所要求的。 您看到的结果集显示了每个"岛"的END_TIMESTAMP。 但是在问题陈述中,您希望查看下一组的START_TIMESTAMP。

由于最后一点只是最终SELECT的另一个WINDOW表达式,因此我将其留给您以找出其中的一个:)

打个大熊猫
2楼-- · 2020-09-12 05:10

请提供create table语句和insert命令,以便人们可以测试数据集上的解决方案。

粗暴的香蕉
3楼-- · 2020-09-12 05:20

Hi Lars,

已更新。

谢谢

Prachi

4楼-- · 2020-09-12 05:08

Hi Lars,

非常感谢您为我提供帮助。 如您所知,对于END_TIMESTAMP,我想查看下一组的START_TIMESTAMP。 我按照您的建议在下面使用了WINDOW函数-

引导(s.timestamp)结束(按s.seq划分s.id顺序)end_timestamp

有了END_TIMESTAMP的此功能,我认为我根本不需要"端点"查询。 如果我错了,请纠正我。


致谢,
普拉奇

一周热门 更多>

点击此处---> EasySAP.com 一起学习S4 HANA ...

相关问答