英文:
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, 'IW') - 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, 'IW') - 1 ) AND TRUNC (SYSDATE)
Here's a test case demonstrating the difference:
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
You can see that for the two Sunday rows, your version returns the previous Sunday, whereas the amended version returns the current Sunday.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论