如何按ISO周排序,从今天的周数开始

时间:2017-10-30 09:15:55

标签: sql oracle

我想从oracle查询数据并按周排序,但结果从第52周开始,现在实际上是第44周。 这是我的sql:

SELECT *
FROM (SELECT
        to_char(contract.MIGRATION_SUCCESS_DATE,'yyyy-iw') metric,
        sum(contract.BLIS_MRR)                    mrr,
        count(contract.CONTRACT_ID)               count
      FROM (SELECT DISTINCT
              CONTRACT_ID,
              BLIS_MRR,
              MIGRATION_SUCCESS_DATE
            FROM MR_MIGRATION_SITE) contract WHERE MIGRATION_SUCCESS_DATE < sysdate
      GROUP BY to_char(contract.MIGRATION_SUCCESS_DATE,'yyyy-iw'))
ORDER BY metric DESC;

,结果如下: enter image description here

2 个答案:

答案 0 :(得分:3)

我认为你必须使用格式to_char(contract.MIGRATION_SUCCESS_DATE,'iyyy-iw')

ISO周的年份可能与实际年份不同,例如2017年1月1日是2016年第52周,即根据ISO定义2016-W52

我建议符合ISO 8601

的格式'iyyy-"W"iw'

或许可以将GROUP BY子句更改为GROUP BY TRUNC(contract.MIGRATION_SUCCESS_DATE,'iw')

答案 1 :(得分:0)

当该日期的星期日和星期一在不同年份时,您会遇到问题。

要解决此问题,您可以使用@Wernfried Domscheit's solutioniyyy-iw格式获取ISO年份和星期:

TO_CHAR( contract.MIGRATION_SUCCESS_DATE, 'IYYY-IW' )

初始(不正确)解决方案

要修复它,您可以将日期截断到ISO周的开头,然后将其转换为yyyy-iw格式

TO_CHAR(
  TRUNC( contract.MIGRATION_SUCCESS_DATE, 'IW' )
  'yyyy-iw'
)

例如:

SQL Fiddle

Oracle 11g R2架构设置

CREATE TABLE test_data( dt ) AS
SELECT DATE '2016-12-31' FROM DUAL UNION ALL
SELECT DATE '2017-01-01' FROM DUAL UNION ALL
SELECT DATE '2017-01-02' FROM DUAL UNION ALL
SELECT DATE '2014-12-31' FROM DUAL;

查询1

SELECT dt,
       TO_CHAR( dt, 'iyyy-iw' ) AS trunc_iw,
       TO_CHAR( TRUNC( dt, 'IW' ), 'yyyy-iw' ) AS trunc_iw2,
       TO_CHAR( dt, 'yyyy-iw' ) AS non_trunc_iw
FROM   test_data

<强> Results

|                   DT | TRUNC_IW | TRUNC_IW2 | NON_TRUNC_IW |
|----------------------|----------|-----------|--------------|
| 2016-12-31T00:00:00Z |  2016-52 |   2016-52 |      2016-52 |
| 2017-01-01T00:00:00Z |  2016-52 |   2016-52 |      2017-52 |
| 2017-01-02T00:00:00Z |  2017-01 |   2017-01 |      2017-01 |
| 2014-12-31T00:00:00Z |  2015-01 |   2014-01 |      2014-01 | -- initial version is incorrect for this date