如何更改Oracle TRUNC用于启动一周的日期

时间:2013-12-14 03:05:01

标签: sql oracle

我有以下SQL:

SELECT SUM(theNumberCol) qty, TRUNC(theDateCol, 'WW') weekDate
FROM theTable
GROUP BY TRUNC(theDateCol, 'WW');

这适用于查找每周的数字和的总和。问题是本周似乎从星期二开始。例如,“12/17/2013 8:56:05 AM”被截断为“12/17/2013”​​,而“12/16/2013 5:09:25 AM”被截断为“12/10/2013”​​。

  1. Oracle如何确定本周开始的哪一天?
  2. 我可以在星期六更改星期开始吗?

4 个答案:

答案 0 :(得分:2)

有两种不同的计算方法:经典oracle,它计算week = int(dayOfYear + 6)/ 7,以及iso模式,它使用ISO 8601。格式WW使用经典计算,而格式IW使用ISO标准。

正如你所看到的,WW并没有在一周的任何固定日开始这一周,它只是从1月1日开始的一周,无论哪一天。如果您居住在符合国际标准的任何国家,IW应该适合您。

答案 1 :(得分:1)

这取决于您当地的NLS_TERRITORY,这是第一天。例如。 “德国”星期一将回归。 “美国”周日回归,“埃及”周六回归。

使用alter session set nls_territory ='germany';例如

答案 2 :(得分:1)

距离截断日期7天,然后找到该日期的下一个星期六:

SQL Fiddle

Oracle 11g R2架构设置

CREATE TABLE theTable ( theNumberCol, theDateCol ) AS
          SELECT  1, TO_DATE( '20131202 23:15:52', 'YYYYMMDD HH24:MI:SS' ) FROM DUAL
UNION ALL SELECT  2, TO_DATE( '20131203', 'YYYYMMDD' ) FROM DUAL
UNION ALL SELECT  3, TO_DATE( '20131204', 'YYYYMMDD' ) FROM DUAL
UNION ALL SELECT  4, TO_DATE( '20131205', 'YYYYMMDD' ) FROM DUAL
UNION ALL SELECT  5, TO_DATE( '20131206', 'YYYYMMDD' ) FROM DUAL
UNION ALL SELECT  6, TO_DATE( '20131207', 'YYYYMMDD' ) FROM DUAL
UNION ALL SELECT  7, TO_DATE( '20131208', 'YYYYMMDD' ) FROM DUAL
UNION ALL SELECT  8, TO_DATE( '20131209', 'YYYYMMDD' ) FROM DUAL
UNION ALL SELECT  9, TO_DATE( '20131210', 'YYYYMMDD' ) FROM DUAL
UNION ALL SELECT 10, TO_DATE( '20131211', 'YYYYMMDD' ) FROM DUAL
UNION ALL SELECT 11, TO_DATE( '20131212', 'YYYYMMDD' ) FROM DUAL
UNION ALL SELECT 12, TO_DATE( '20131213', 'YYYYMMDD' ) FROM DUAL
UNION ALL SELECT 13, TO_DATE( '20131214', 'YYYYMMDD' ) FROM DUAL
UNION ALL SELECT 14, TO_DATE( '20131215', 'YYYYMMDD' ) FROM DUAL
UNION ALL SELECT 15, TO_DATE( '20131216', 'YYYYMMDD' ) FROM DUAL
UNION ALL SELECT 16, TO_DATE( '20131217', 'YYYYMMDD' ) FROM DUAL;

查询1

SELECT SUM(theNumberCol) AS qty,
       NEXT_DAY( TRUNC( theDateCol ) - INTERVAL '7' DAY, 'SATURDAY' ) weekDate
FROM   theTable
GROUP BY
       NEXT_DAY( TRUNC( theDateCol ) - INTERVAL '7' DAY, 'SATURDAY' )
ORDER BY
       weekDate ASC

<强> Results

| QTY |                        WEEKDATE |
|-----|---------------------------------|
|  15 | November, 30 2013 00:00:00+0000 |
|  63 | December, 07 2013 00:00:00+0000 |
|  58 | December, 14 2013 00:00:00+0000 |

答案 3 :(得分:0)

我不知道改变TRUNC(...)的行为是可能的(并且偏离文档可能会导致问题)。但是,还有另一种解决方案(可能表现更好):

你想要的是Calendar Table(例如SQL Server,但基本概念适用)。如果你没有,我建议创建(和索引)一个。例如,无论你的星期是星期六开始,使用日历表都会使这个变得微不足道:

SELECT
FROM WeekRange.weekStart, SUM(theTable.theNumberCol)
JOIN (SELECT dateValue as weekStart, dateValue + 7 as nextWeekStart
      FROM Calendar
      WHERE nameOfDay = 'Saturday') WeekRange
  ON theTable.theDateCol >= WeekRange.weekStart 
     AND theTable.theDateCol < WeekRange.nextWeekStart
GROUP BY WeekRange.weekStart

当然,根据需要添加/替换条件。此版本也更有可能在相关列上使用任何索引。