首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何在30分钟间隔内对24小时数据进行分组,以获取计数?

如何在30分钟间隔内对24小时数据进行分组,以获取计数?
EN

Stack Overflow用户
提问于 2021-07-25 20:00:52
回答 3查看 84关注 0票数 1

我在sales表中有一个字段名为timestamp,其数据格式为: 20210725.1800,表示2021年07月25日00:30:00 AM

现在,如果我想要在20210725.0000到20210725.1800之间的30分钟间隔内计算销售额,我可以简单地写下:

代码语言:javascript
运行
复制
def var k as int no-undo.

for each sales no-lock 
   where salesdate =  07/25/2021 
   and   timestamp >= 20210725.0000
   and   timestamp <= 20210725.1800
:

   if available sales then do:

      k = k + 1.
      pause 0.

      display k with frame f.

   end.

end.

但是,我不想通过更改timestamp字段的开始和结束时间来运行同一查询24次。

因此,我正在寻找一种更聪明的方法来找出这个时间戳字段上按30分钟间隔分组的全天销售计数。

EN

回答 3

Stack Overflow用户

发布于 2021-07-26 03:23:27

你可以按照下面的思路做一些事情。如果您还想要多个日期,也可以按salesdate对查询进行排序,尽管您必须在每个新日期清除整数数组(有关如何执行此操作的信息,请参阅byandbreak by`文档)。

ts变量的计算将取决于十进制值是如何构造的:.1800和.18002是否在同一个30分钟的时段中?

代码语言:javascript
运行
复制
def var numSales as integer extent 24 no-undo.
def var k as integer no-undo.
def var ts as integer.

for each sales 
 no-lock 
   where salesdate eq 07/25/2021:

    // get the timestamp for the day
    // this could use a calculation like the below,
    // or a simple CASE statement
    ts = 10000 * (timestamp - decimal(string(year(salesdate)) + string(month(salesdate)) + string(day(salesdate)))).

    // find the 30-minute slot. +1 makes it a 'ceiling'
    numSales[integer(ts / (30 * 60)) + 1] += 1.
end.

do k = 1 to 24 with frame f:
    displ
       k (k * 30 * 60) numsales[k].
end.    
票数 1
EN

Stack Overflow用户

发布于 2021-08-06 14:51:09

如果我跳过我关于时间戳是如何构造的问题,您可以使用break by来获取结果:

代码语言:javascript
运行
复制
def temp-table ttsales no-undo
   field salesdate as date
   field timestamp as decimal
   .

function createSale returns logical (
   i_detimestamp as decimal
):

   def buffer busale for ttsales.

   def var idate  as int.
   def var iyear  as int.
   def var imonth as int.
   def var iday   as int.

   assign
      idate  = truncate( i_detimestamp, 0 )
      iyear  = truncate( idate / 10000, 0 )
      idate  = idate - iyear * 10000
      imonth = truncate( idate / 100, 0 )
      iday   = idate - imonth * 100      
      .

   create busale.
   assign
      busale.salesdate = date( imonth, iday, iyear )
      busale.timestamp = i_detimestamp
      .

end function.

createSale( 20210725.0000 ).
createSale( 20210725.0001 ).
createSale( 20210725.1799 ).
createSale( 20210725.1800 ).
createSale( 20210725.1801 ).

def buffer busale for ttsales.

def var irecords as int.
def var idate    as int.

for each busale
   where busale.salesdate = 07/25/2021
break 
   by truncate( busale.timestamp * 10000 / 1800, 0 )
:

   irecords = irecords + 1.

   if last-of( truncate( busale.timestamp * 10000 / 1800, 0 ) ) then do:
      display 
         int( truncate( ( ( busale.timestamp * 10000 ) modulo 10000 ) / 1800, 0 ) )
         irecords
         .
      irecords = 0.
   end.

end.

ABLdojo中尝试一下。

票数 1
EN

Stack Overflow用户

发布于 2021-07-26 21:18:33

只要每个子查询的效率与一个大查询的效率一样高,那么运行同一查询24次(或任何其他)并没有什么错。

如果你的代码对3年后试图理解你所做的事情的维护程序员来说更加清晰,那么这样做并没有错。

下面的示例只使用了一个日期字段,因为无处不在的"sports“数据库没有任何具有您的示例所具有的date.time样式的字段,但是它应该很容易推断:

代码语言:javascript
运行
复制
define variable n as integer no-undo.
define variable d as date    no-undo.

define variable b as handle no-undo.
define variable q as handle no-undo.

create buffer b for table "order".
create query q.
q:set-buffers( b ).

do d = 1/1/1998 to 1/31/1998:

  n = 0.
  q:query-prepare( substitute( 'preselect each order no-lock where orderDate = &1', d )).
  q:query-open no-error.
  if q:query-off-end = no then
    n = q:num-results no-error.
  display d n with frame a down.
  down with frame a.
  q:query-close no-error.

end.
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/68518351

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档