如何计算从给定日期算起的周数?

时间:2016-06-22 06:46:49

标签: database oracle plsql

我有一个用户可以选择开始日期和结束日期的方案。 我应该从他的开始日期到结束日期周显示数据,其中第1周应该包含从该特定周的开始日期到结束日期的数据, 第2周 - 应该是下周的数据。等等 如果用户选择的开始日期是22-jun-16,我将如何将其显示为第1周?

1 个答案:

答案 0 :(得分:0)

由于您没有提供任何表结构,我正在创建下表以解释解决方案。

CREATE TABLE sales
(
sale_date DATE,
sale_amt NUMBER(20,2)
)

现在,在此表中插入一些示例数据。

您可以使用以下查询获取按周计算的数据。

SELECT wk_start, 
       sale_amt, 
       'Week ' || ROWNUM
FROM
(
SELECT wk_start, 
       sale_amt
FROM ( SELECT TRUNC(sale_date ,'iw') wk_start, 
              SUM(sale_amt) sale_amt 
       FROM   sales
       WHERE sale_date BETWEEN '06/23/2016' AND '08/05/2016'
       GROUP BY TRUNC(sale_date ,'iw')
     )
ORDER BY wk_start
)

最内部的查询将获得表格中任何日期的一周的第一天以及该周的总销售额(或任何其他度量)。然后我们按周开始日期排序最内部查询的结果,并将字符串Week添加到它前面。

以下是适合您确切要求的增强型解决方案。

SELECT CASE WHEN ROWNUM = 1 THEN TO_DATE('06/23/2016','MM/DD/YYYY') ELSE wk_start END AS wk_start,
       mon,
       row_number() over(partition by mon order by rownum) as week_num,
       sale_amt 
FROM
( SELECT TRUNC(sale_date ,'iw')-1 wk_start, 
             TO_CHAR(TRUNC(sale_date ,'iw')-1, 'MON') mon, 
             SUM(sale_amt) sale_amt 
       FROM   sales
       WHERE sale_date BETWEEN '06/23/2016' AND '08/05/2016'
       GROUP BY TRUNC(sale_date ,'iw')-1, 
                TO_CHAR(TRUNC(sale_date ,'iw')-1, 'MON') 
       ORDER BY TRUNC(sale_date ,'iw')-1 
     )
ORDER BY wk_start

内部查询获取星期几的开始日期。 row_number()函数将增加周数,直到月份保持不变。月份更改后,它会将其重置为1.主查询的第一行将显示您已传递的参数,而不是第一行的周开始日期。对于所有剩余的行,它将打印周开始日期。

以下查询将根据您的要求格式化日期。如果您需要查询的任何其他字段,请包含所有查询的SELECT列表和最内部查询的GROUP BY列表。

SELECT 
'Week ' || week_num || '(' || to_char(wk_start,'dd-mon-yyyy') || ' to ' || to_char(wk_end,'dd-mon-yyyy') || ')' as Week,
sale_amt 
FROM
(
SELECT CASE WHEN ROWNUM = 1 THEN TO_DATE('06/23/2016','MM/DD/YYYY') ELSE wk_start END AS wk_start,
       wk_end AS wk_end,
       mon,
       row_number() over(partition by mon order by rownum) as week_num,
       sale_amt 
FROM
( SELECT TRUNC(sale_date ,'iw')-1 wk_start, 
         TRUNC(sale_date ,'iw')+5 wk_end,
         TO_CHAR(TRUNC(sale_date ,'iw')-1, 'MON') mon, 
         SUM(sale_amt) sale_amt 
       FROM   sales
       WHERE sale_date BETWEEN '06/23/2016' AND '08/05/2016'
       GROUP BY TRUNC(sale_date ,'iw')-1, 
                TRUNC(sale_date ,'iw')+5,
                TO_CHAR(TRUNC(sale_date ,'iw')-1, 'MON') 
       ORDER BY TRUNC(sale_date ,'iw')-1 
     )
ORDER BY wk_start
)