Week starting hour gives previous week date instead of current week

huangapple go评论81阅读模式
英文:

Week starting hour gives previous week date instead of current week

问题

在我们的项目中,我们正在维护客户每周的消费额。为此,我们每周的开始都会重置客户的限额。

每当客户进行交易时,我们都会使用以下查询来更新他的每周消费额。

UPDATE SUMMARY 
SET WEEKLIMIT = (
       SELECT NVL (SUM (AMT / 100), 0) 
       FROM TRANSACTION 
       WHERE MOBILENO = :mobileNumber 
       AND TRUNC(TXNDT) BETWEEN (TRUNC (SYSTIMESTAMP, 'IW') - 1 ) AND TRUNC (SYSTIMESTAMP)
) WHERE MOBILENO = :mobileNumber 

但问题是,在每周的“星期日00:00:01到01:00:00”的时候,上面的查询会更新上一周的限额,而不是当前周的限额。

当我在星期日的第一小时运行此查询时,它返回:

200

但从下一个小时开始,它只返回:

100

为什么一周的开始小时会返回上一周的数据。

这是我的NLS参数:

NLS_LANGUAGE		ENGLISH
NLS_TERRITORY		INDIA
NLS_CURRENCY		Rs
NLS_ISO_CURRENCY	INDIA
NLS_NUMERIC_CHARACTERS	.,
NLS_CALENDAR		GREGORIAN
NLS_DATE_FORMAT		DD-MM-RR
NLS_DATE_LANGUAGE	ENGLISH
NLS_SORT		BINARY
NLS_TIME_FORMAT		HH12:MI:SSXFF AM
NLS_TIMESTAMP_FORMAT	DD-MM-RR HH12:MI:SSXFF AM
NLS_TIME_TZ_FORMAT	HH12:MI:SSXFF AM TZR
NLS_TIMESTAMP_TZ_FORMAT	DD-MM-RR HH12:MI:SSXFF AM TZR
NLS_DUAL_CURRENCY	Rs
NLS_COMP		BINARY
NLS_LENGTH_SEMANTICS	BYTE
NLS_NCHAR_CONV_EXCP	FALSE

任何帮助都将不胜感激!!!

英文:

In our project we are maintaining a customers weekly spend. For that every week start we are resetting a customer limit.

Whenever customer doing a transaction we are updating his weekly spend by using the below query.

UPDATE SUMMARY 
SET WEEKLIMIT = (
       SELECT NVL (SUM (AMT / 100), 0) 
       FROM TRANSACTION 
       WHERE MOBILENO = :mobileNumber 
       AND TRUNC(TXNDT) BETWEEN (TRUNC (SYSTIMESTAMP, 'IW') - 1 ) AND TRUNC (SYSTIMESTAMP)
) WHERE MOBILENO = :mobileNumber 

But the problem is customer who are doing transaction in sunday 00:00:01 to 01:00:00 hours, the above query updating the previous week limits
instead of current week.

SUMMARY

MOBILENUMBER  AMT TXNDATE    
0000000000    10000 26-12-2019 09:05:34
0000000000    10000 28-12-2019 11:05:34
0000000000    10000 29-12-2019 00:01:35

When I run this query in sunday first hour it returning

200

But from next hour

it returning only

100

Why the starting hour of week gives the previous week data.

Here is my NLS parameters

NLS_LANGUAGE		ENGLISH
NLS_TERRITORY		INDIA
NLS_CURRENCY		Rs
NLS_ISO_CURRENCY	INDIA
NLS_NUMERIC_CHARACTERS	.,
NLS_CALENDAR		GREGORIAN
NLS_DATE_FORMAT		DD-MM-RR
NLS_DATE_LANGUAGE	ENGLISH
NLS_SORT		BINARY
NLS_TIME_FORMAT		HH12:MI:SSXFF AM
NLS_TIMESTAMP_FORMAT	DD-MM-RR HH12:MI:SSXFF AM
NLS_TIME_TZ_FORMAT	HH12:MI:SSXFF AM TZR
NLS_TIMESTAMP_TZ_FORMAT	DD-MM-RR HH12:MI:SSXFF AM TZR
NLS_DUAL_CURRENCY	Rs
NLS_COMP		BINARY
NLS_LENGTH_SEMANTICS	BYTE
NLS_NCHAR_CONV_EXCP	FALSE

Any help will be greatly appreciated!!!!

答案1

得分: 2

我认为您的问题出在日期处理上。您目前的逻辑是:

TRUNC(TXNDT) BETWEEN (TRUNC(SYSTIMESTAMP, 'IW') - 1) AND TRUNC(SYSTIMESTAMP)

您希望这将一周的开始日期设为星期日。然而,您的逻辑有问题 - 您的逻辑实际上是“获取当前周的星期一并减去一天”。如果您的日期是星期日,这意味着首先获取上一个星期一,然后减去一天,使其成为上一个星期日。

您首先需要将星期日转换为星期一(通过添加一天),将其截断为一周的第一天(星期一),然后再减去一天。

这意味着您的条件应该如下所示:

TRUNC(TXNDT) BETWEEN (TRUNC(SYSDATE + 1, 'IW') - 1) AND TRUNC(SYSDATE)

以下是演示差异的测试案例:

WITH dts AS (
  SELECT TRUNC(SYSDATE, 'mm') - 1 + LEVEL dt
  FROM dual
  CONNECT BY LEVEL <= 13
)
SELECT dt,
       to_char(dt, 'Dy') day_of_week,
       TRUNC(dt, 'iw') monday_start_week,
       TRUNC(dt, 'iw') - 1 your_sunday_start_week,
       TRUNC(dt + 1, 'iw') - 1 actual_sunday_start_week
FROM dts;

结果如下:

DT          DAY_OF_WEEK MONDAY_START_WEEK YOUR_SUNDAY_START_WEEK ACTUAL_SUNDAY_START_WEEK
----------- ----------- ----------------- ---------------------- ------------------------
01/01/2020  Wed         30/12/2019        29/12/2019             29/12/2019
02/01/2020  Thu         30/12/2019        29/12/2019             29/12/2019
03/01/2020  Fri         30/12/2019        29/12/2019             29/12/2019
04/01/2020  Sat         30/12/2019        29/12/2019             29/12/2019
05/01/2020  Sun         30/12/2019        29/12/2019             05/01/2020  <-----
06/01/2020  Mon         06/01/2020        05/01/2020             05/01/2020
07/01/2020  Tue         06/01/2020        05/01/2020             05/01/2020
08/01/2020  Wed         06/01/2020        05/01/2020             05/01/2020
09/01/2020  Thu         06/01/2020        05/01/2020             05/01/2020
10/01/2020  Fri         06/01/2020        05/01/2020             05/01/2020
11/01/2020  Sat         06/01/2020        05/01/2020             05/01/2020
12/01/2020  Sun         06/01/2020        05/01/2020             12/01/2020  <-----
13/01/2020  Mon         13/01/2020        12/01/2020             12/01/2020

可以看到,在两个星期日的情况下,您的版本返回的是上一个星期日,而修改后的版本返回的是当前星期日。

英文:

I believe your issue lies in your date manipulation. You are doing:

TRUNC(TXNDT) BETWEEN (TRUNC (SYSTIMESTAMP, &#39;IW&#39;) - 1 ) AND TRUNC (SYSTIMESTAMP)

and expecting that to make the start of the week a Sunday.

However, you haven't done this correctly - your logic says "take the Monday of the current week and subtract a day from it". If your day is a Sunday, that means it first gets the previous Monday and subtracts a day to make it the previous Sunday.

What you must first do is turn the Sunday into a Monday (by adding a day), truncate it to the first day of the week (Monday), and then subtract a day.

Which means your predicate should now look like:

TRUNC(TXNDT) BETWEEN (TRUNC (SYSDATE + 1, &#39;IW&#39;) - 1 ) AND TRUNC (SYSDATE)

Here's a test case demonstrating the difference:

WITH dts AS (SELECT TRUNC(SYSDATE, &#39;mm&#39;) - 1 + LEVEL dt
             FROM   dual
             CONNECT BY LEVEL &lt;= 13)
SELECT dt,
       to_char(dt, &#39;Dy&#39;) day_of_week,
       TRUNC(dt, &#39;iw&#39;) monday_start_week,
       TRUNC(dt, &#39;iw&#39;) - 1 your_sunday_start_week,
       TRUNC(dt + 1, &#39;iw&#39;) - 1 actual_sunday_start_week
FROM   dts;

DT          DAY_OF_WEEK MONDAY_START_WEEK YOUR_SUNDAY_START_WEEK ACTUAL_SUNDAY_START_WEEK
----------- ----------- ----------------- ---------------------- ------------------------
01/01/2020  Wed         30/12/2019        29/12/2019             29/12/2019
02/01/2020  Thu         30/12/2019        29/12/2019             29/12/2019
03/01/2020  Fri         30/12/2019        29/12/2019             29/12/2019
04/01/2020  Sat         30/12/2019        29/12/2019             29/12/2019
05/01/2020  Sun         30/12/2019        29/12/2019             05/01/2020  &lt;-----
06/01/2020  Mon         06/01/2020        05/01/2020             05/01/2020
07/01/2020  Tue         06/01/2020        05/01/2020             05/01/2020
08/01/2020  Wed         06/01/2020        05/01/2020             05/01/2020
09/01/2020  Thu         06/01/2020        05/01/2020             05/01/2020
10/01/2020  Fri         06/01/2020        05/01/2020             05/01/2020
11/01/2020  Sat         06/01/2020        05/01/2020             05/01/2020
12/01/2020  Sun         06/01/2020        05/01/2020             12/01/2020  &lt;-----
13/01/2020  Mon         13/01/2020        12/01/2020             12/01/2020

You can see that for the two Sunday rows, your version returns the previous Sunday, whereas the amended version returns the current Sunday.

huangapple
  • 本文由 发表于 2020年1月3日 15:57:38
  • 转载请务必保留本文链接:https://go.coder-hub.com/59575021.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定